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.
- checksums.yaml +7 -0
- data/LICENSE +22 -0
- data/exe/ngage +55 -0
- data/lib/ngage.rb +3 -0
- data/lib/ngage/jekyll.rb +204 -0
- data/lib/ngage/jekyll/cleaner.rb +111 -0
- data/lib/ngage/jekyll/collection.rb +235 -0
- data/lib/ngage/jekyll/command.rb +103 -0
- data/lib/ngage/jekyll/commands/build.rb +93 -0
- data/lib/ngage/jekyll/commands/clean.rb +45 -0
- data/lib/ngage/jekyll/commands/doctor.rb +173 -0
- data/lib/ngage/jekyll/commands/help.rb +34 -0
- data/lib/ngage/jekyll/commands/new.rb +157 -0
- data/lib/ngage/jekyll/commands/new_theme.rb +42 -0
- data/lib/ngage/jekyll/commands/serve.rb +354 -0
- data/lib/ngage/jekyll/commands/serve/live_reload_reactor.rb +122 -0
- data/lib/ngage/jekyll/commands/serve/livereload_assets/livereload.js +1183 -0
- data/lib/ngage/jekyll/commands/serve/servlet.rb +203 -0
- data/lib/ngage/jekyll/commands/serve/websockets.rb +81 -0
- data/lib/ngage/jekyll/configuration.rb +391 -0
- data/lib/ngage/jekyll/converter.rb +54 -0
- data/lib/ngage/jekyll/converters/identity.rb +41 -0
- data/lib/ngage/jekyll/converters/markdown.rb +116 -0
- data/lib/ngage/jekyll/converters/markdown/kramdown_parser.rb +122 -0
- data/lib/ngage/jekyll/converters/smartypants.rb +70 -0
- data/lib/ngage/jekyll/convertible.rb +253 -0
- data/lib/ngage/jekyll/deprecator.rb +50 -0
- data/lib/ngage/jekyll/document.rb +503 -0
- data/lib/ngage/jekyll/drops/collection_drop.rb +20 -0
- data/lib/ngage/jekyll/drops/document_drop.rb +69 -0
- data/lib/ngage/jekyll/drops/drop.rb +209 -0
- data/lib/ngage/jekyll/drops/excerpt_drop.rb +15 -0
- data/lib/ngage/jekyll/drops/jekyll_drop.rb +32 -0
- data/lib/ngage/jekyll/drops/site_drop.rb +56 -0
- data/lib/ngage/jekyll/drops/static_file_drop.rb +14 -0
- data/lib/ngage/jekyll/drops/unified_payload_drop.rb +26 -0
- data/lib/ngage/jekyll/drops/url_drop.rb +89 -0
- data/lib/ngage/jekyll/entry_filter.rb +127 -0
- data/lib/ngage/jekyll/errors.rb +20 -0
- data/lib/ngage/jekyll/excerpt.rb +180 -0
- data/lib/ngage/jekyll/external.rb +76 -0
- data/lib/ngage/jekyll/filters.rb +390 -0
- data/lib/ngage/jekyll/filters/date_filters.rb +110 -0
- data/lib/ngage/jekyll/filters/grouping_filters.rb +64 -0
- data/lib/ngage/jekyll/filters/url_filters.rb +68 -0
- data/lib/ngage/jekyll/frontmatter_defaults.rb +233 -0
- data/lib/ngage/jekyll/generator.rb +5 -0
- data/lib/ngage/jekyll/hooks.rb +106 -0
- data/lib/ngage/jekyll/layout.rb +62 -0
- data/lib/ngage/jekyll/liquid_extensions.rb +22 -0
- data/lib/ngage/jekyll/liquid_renderer.rb +63 -0
- data/lib/ngage/jekyll/liquid_renderer/file.rb +56 -0
- data/lib/ngage/jekyll/liquid_renderer/table.rb +98 -0
- data/lib/ngage/jekyll/log_adapter.rb +151 -0
- data/lib/ngage/jekyll/mime.types +825 -0
- data/lib/ngage/jekyll/page.rb +185 -0
- data/lib/ngage/jekyll/page_without_a_file.rb +14 -0
- data/lib/ngage/jekyll/plugin.rb +92 -0
- data/lib/ngage/jekyll/plugin_manager.rb +115 -0
- data/lib/ngage/jekyll/publisher.rb +23 -0
- data/lib/ngage/jekyll/reader.rb +154 -0
- data/lib/ngage/jekyll/readers/collection_reader.rb +22 -0
- data/lib/ngage/jekyll/readers/data_reader.rb +75 -0
- data/lib/ngage/jekyll/readers/layout_reader.rb +70 -0
- data/lib/ngage/jekyll/readers/page_reader.rb +25 -0
- data/lib/ngage/jekyll/readers/post_reader.rb +72 -0
- data/lib/ngage/jekyll/readers/static_file_reader.rb +25 -0
- data/lib/ngage/jekyll/readers/theme_assets_reader.rb +51 -0
- data/lib/ngage/jekyll/regenerator.rb +195 -0
- data/lib/ngage/jekyll/related_posts.rb +52 -0
- data/lib/ngage/jekyll/renderer.rb +266 -0
- data/lib/ngage/jekyll/site.rb +476 -0
- data/lib/ngage/jekyll/static_file.rb +169 -0
- data/lib/ngage/jekyll/stevenson.rb +60 -0
- data/lib/ngage/jekyll/tags/highlight.rb +108 -0
- data/lib/ngage/jekyll/tags/include.rb +226 -0
- data/lib/ngage/jekyll/tags/link.rb +40 -0
- data/lib/ngage/jekyll/tags/post_url.rb +104 -0
- data/lib/ngage/jekyll/theme.rb +73 -0
- data/lib/ngage/jekyll/theme_builder.rb +121 -0
- data/lib/ngage/jekyll/url.rb +160 -0
- data/lib/ngage/jekyll/utils.rb +370 -0
- data/lib/ngage/jekyll/utils/ansi.rb +57 -0
- data/lib/ngage/jekyll/utils/exec.rb +26 -0
- data/lib/ngage/jekyll/utils/internet.rb +37 -0
- data/lib/ngage/jekyll/utils/platforms.rb +82 -0
- data/lib/ngage/jekyll/utils/thread_event.rb +31 -0
- data/lib/ngage/jekyll/utils/win_tz.rb +75 -0
- data/lib/ngage/site_template/.gitignore +5 -0
- data/lib/ngage/site_template/404.html +25 -0
- data/lib/ngage/site_template/_config.yml +47 -0
- data/lib/ngage/site_template/_posts/0000-00-00-welcome-to-jekyll.markdown.erb +29 -0
- data/lib/ngage/site_template/about.markdown +18 -0
- data/lib/ngage/site_template/index.markdown +6 -0
- data/lib/ngage/theme_template/CODE_OF_CONDUCT.md.erb +74 -0
- data/lib/ngage/theme_template/Gemfile +4 -0
- data/lib/ngage/theme_template/LICENSE.txt.erb +21 -0
- data/lib/ngage/theme_template/README.md.erb +52 -0
- data/lib/ngage/theme_template/_layouts/default.html +1 -0
- data/lib/ngage/theme_template/_layouts/page.html +5 -0
- data/lib/ngage/theme_template/_layouts/post.html +5 -0
- data/lib/ngage/theme_template/example/_config.yml.erb +1 -0
- data/lib/ngage/theme_template/example/_post.md +12 -0
- data/lib/ngage/theme_template/example/index.html +14 -0
- data/lib/ngage/theme_template/example/style.scss +7 -0
- data/lib/ngage/theme_template/gitignore.erb +6 -0
- data/lib/ngage/theme_template/theme.gemspec.erb +19 -0
- data/lib/ngage/version.rb +5 -0
- metadata +328 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA1:
|
|
3
|
+
metadata.gz: 6d8c2ce22da23b23b6b841fe4d12997fe28d7508
|
|
4
|
+
data.tar.gz: 96bb7df108b7b4b8e1a29173199cbf59b9aed3b0
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: f5020313d3402c110730edb0d27cf7297760f4a50038848b46429835ca83c83383f2acc57e3ef135b1e66899b9f17996a535b82519894ecc6fa4d0d41d221f2b
|
|
7
|
+
data.tar.gz: 5d1483a217e4343da15df13a60af2e8ebb7b2e002a451cc2d7866dc87edb039822f528f1307cb020c6a5812a173d8b03bd16d4e3a22783ee1f122259efb43823
|
data/LICENSE
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
The MIT License (MIT)
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2008-2018 Tom Preston-Werner and Jekyll contributors
|
|
4
|
+
Copyright (c) 2018-present Ashwin Maroli
|
|
5
|
+
|
|
6
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
7
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
8
|
+
in the Software without restriction, including without limitation the rights
|
|
9
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
10
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
11
|
+
furnished to do so, subject to the following conditions:
|
|
12
|
+
|
|
13
|
+
The above copyright notice and this permission notice shall be included in all
|
|
14
|
+
copies or substantial portions of the Software.
|
|
15
|
+
|
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
17
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
18
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
19
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
20
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
21
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
22
|
+
SOFTWARE.
|
data/exe/ngage
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
STDOUT.sync = true
|
|
5
|
+
|
|
6
|
+
$LOAD_PATH.unshift File.expand_path("../lib", __dir__)
|
|
7
|
+
|
|
8
|
+
require "ngage"
|
|
9
|
+
require "mercenary"
|
|
10
|
+
|
|
11
|
+
Jekyll::PluginManager.require_from_bundler
|
|
12
|
+
Jekyll::Deprecator.process(ARGV)
|
|
13
|
+
|
|
14
|
+
Mercenary.program(:ngage) do |p|
|
|
15
|
+
p.version NGage::VERSION
|
|
16
|
+
p.description "An enhanced fork of Jekyll, NGage is yet another static site generator in Ruby"
|
|
17
|
+
p.syntax "ngage <subcommand> [options]"
|
|
18
|
+
|
|
19
|
+
p.option "source", "-s", "--source [DIR]", "Source directory (defaults to ./)"
|
|
20
|
+
p.option "destination", "-d", "--destination [DIR]",
|
|
21
|
+
"Destination directory (defaults to ./_site)"
|
|
22
|
+
p.option "safe", "--safe", "Safe mode (defaults to false)"
|
|
23
|
+
p.option "plugins_dir", "-p", "--plugins PLUGINS_DIR1[,PLUGINS_DIR2[,...]]", Array,
|
|
24
|
+
"Plugins directory (defaults to ./_plugins)"
|
|
25
|
+
p.option "layouts_dir", "--layouts DIR", String,
|
|
26
|
+
"Layouts directory (defaults to ./_layouts)"
|
|
27
|
+
p.option "profile", "--profile", "Generate a Liquid rendering profile"
|
|
28
|
+
|
|
29
|
+
Jekyll::External.require_if_present(Jekyll::External.blessed_gems) do |g, ver_constraint|
|
|
30
|
+
cmd = g.split("-").last
|
|
31
|
+
p.command(cmd.to_sym) do |c|
|
|
32
|
+
c.syntax cmd
|
|
33
|
+
c.action do
|
|
34
|
+
Jekyll.logger.abort_with "You must install the '#{g}' gem version #{ver_constraint} to use the 'ngage #{cmd}' command."
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
Jekyll::Command.subclasses.each { |c| c.init_with_program(p) }
|
|
40
|
+
|
|
41
|
+
p.action do |args, _|
|
|
42
|
+
if args.empty?
|
|
43
|
+
Jekyll.logger.error "A subcommand is required."
|
|
44
|
+
puts p
|
|
45
|
+
abort
|
|
46
|
+
else
|
|
47
|
+
subcommand = args.first
|
|
48
|
+
unless p.has_command? subcommand
|
|
49
|
+
Jekyll.logger.abort_with "fatal: 'ngage #{args.first}' could not" \
|
|
50
|
+
" be found. You may need to install the jekyll-#{args.first} gem" \
|
|
51
|
+
" or a related gem to be able to use this subcommand."
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
data/lib/ngage.rb
ADDED
data/lib/ngage/jekyll.rb
ADDED
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
$LOAD_PATH.unshift __dir__ # For use/testing when no gem is installed
|
|
4
|
+
|
|
5
|
+
# Require all of the Ruby files in the given directory.
|
|
6
|
+
#
|
|
7
|
+
# path - The String relative path from here to the directory.
|
|
8
|
+
#
|
|
9
|
+
# Returns nothing.
|
|
10
|
+
def require_all(path)
|
|
11
|
+
glob = File.join(__dir__, path, "*.rb")
|
|
12
|
+
Dir[glob].sort.each do |f|
|
|
13
|
+
require f
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
# rubygems
|
|
18
|
+
require "rubygems"
|
|
19
|
+
|
|
20
|
+
# stdlib
|
|
21
|
+
require "forwardable"
|
|
22
|
+
require "fileutils"
|
|
23
|
+
require "time"
|
|
24
|
+
require "English"
|
|
25
|
+
require "pathname"
|
|
26
|
+
require "logger"
|
|
27
|
+
require "set"
|
|
28
|
+
require "csv"
|
|
29
|
+
require "json"
|
|
30
|
+
|
|
31
|
+
# 3rd party
|
|
32
|
+
require "pathutil"
|
|
33
|
+
require "addressable/uri"
|
|
34
|
+
require "safe_yaml/load"
|
|
35
|
+
require "liquid"
|
|
36
|
+
require "kramdown"
|
|
37
|
+
require "colorator"
|
|
38
|
+
require "i18n"
|
|
39
|
+
|
|
40
|
+
SafeYAML::OPTIONS[:suppress_warnings] = true
|
|
41
|
+
|
|
42
|
+
module Jekyll
|
|
43
|
+
# internal requires
|
|
44
|
+
autoload :Cleaner, "jekyll/cleaner"
|
|
45
|
+
autoload :Collection, "jekyll/collection"
|
|
46
|
+
autoload :Configuration, "jekyll/configuration"
|
|
47
|
+
autoload :Convertible, "jekyll/convertible"
|
|
48
|
+
autoload :Deprecator, "jekyll/deprecator"
|
|
49
|
+
autoload :Document, "jekyll/document"
|
|
50
|
+
autoload :EntryFilter, "jekyll/entry_filter"
|
|
51
|
+
autoload :Errors, "jekyll/errors"
|
|
52
|
+
autoload :Excerpt, "jekyll/excerpt"
|
|
53
|
+
autoload :External, "jekyll/external"
|
|
54
|
+
autoload :FrontmatterDefaults, "jekyll/frontmatter_defaults"
|
|
55
|
+
autoload :Hooks, "jekyll/hooks"
|
|
56
|
+
autoload :Layout, "jekyll/layout"
|
|
57
|
+
autoload :CollectionReader, "jekyll/readers/collection_reader"
|
|
58
|
+
autoload :DataReader, "jekyll/readers/data_reader"
|
|
59
|
+
autoload :LayoutReader, "jekyll/readers/layout_reader"
|
|
60
|
+
autoload :PostReader, "jekyll/readers/post_reader"
|
|
61
|
+
autoload :PageReader, "jekyll/readers/page_reader"
|
|
62
|
+
autoload :StaticFileReader, "jekyll/readers/static_file_reader"
|
|
63
|
+
autoload :ThemeAssetsReader, "jekyll/readers/theme_assets_reader"
|
|
64
|
+
autoload :LogAdapter, "jekyll/log_adapter"
|
|
65
|
+
autoload :Page, "jekyll/page"
|
|
66
|
+
autoload :PageWithoutAFile, "jekyll/page_without_a_file"
|
|
67
|
+
autoload :PluginManager, "jekyll/plugin_manager"
|
|
68
|
+
autoload :Publisher, "jekyll/publisher"
|
|
69
|
+
autoload :Reader, "jekyll/reader"
|
|
70
|
+
autoload :Regenerator, "jekyll/regenerator"
|
|
71
|
+
autoload :RelatedPosts, "jekyll/related_posts"
|
|
72
|
+
autoload :Renderer, "jekyll/renderer"
|
|
73
|
+
autoload :LiquidRenderer, "jekyll/liquid_renderer"
|
|
74
|
+
autoload :Site, "jekyll/site"
|
|
75
|
+
autoload :StaticFile, "jekyll/static_file"
|
|
76
|
+
autoload :Stevenson, "jekyll/stevenson"
|
|
77
|
+
autoload :Theme, "jekyll/theme"
|
|
78
|
+
autoload :ThemeBuilder, "jekyll/theme_builder"
|
|
79
|
+
autoload :URL, "jekyll/url"
|
|
80
|
+
autoload :Utils, "jekyll/utils"
|
|
81
|
+
autoload :VERSION, "jekyll/version"
|
|
82
|
+
|
|
83
|
+
# extensions
|
|
84
|
+
require "jekyll/plugin"
|
|
85
|
+
require "jekyll/converter"
|
|
86
|
+
require "jekyll/generator"
|
|
87
|
+
require "jekyll/command"
|
|
88
|
+
require "jekyll/liquid_extensions"
|
|
89
|
+
require "jekyll/filters"
|
|
90
|
+
|
|
91
|
+
class << self
|
|
92
|
+
# Public: Tells you which Jekyll environment you are building in so you can skip tasks
|
|
93
|
+
# if you need to. This is useful when doing expensive compression tasks on css and
|
|
94
|
+
# images and allows you to skip that when working in development.
|
|
95
|
+
|
|
96
|
+
def env
|
|
97
|
+
ENV["JEKYLL_ENV"] || "development"
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
# Public: Generate a Jekyll configuration Hash by merging the default
|
|
101
|
+
# options with anything in _config.yml, and adding the given options on top.
|
|
102
|
+
#
|
|
103
|
+
# override - A Hash of config directives that override any options in both
|
|
104
|
+
# the defaults and the config file.
|
|
105
|
+
# See Jekyll::Configuration::DEFAULTS for a
|
|
106
|
+
# list of option names and their defaults.
|
|
107
|
+
#
|
|
108
|
+
# Returns the final configuration Hash.
|
|
109
|
+
def configuration(override = {})
|
|
110
|
+
config = Configuration.new
|
|
111
|
+
override = Configuration[override].stringify_keys
|
|
112
|
+
unless override.delete("skip_config_files")
|
|
113
|
+
config = config.read_config_files(config.config_files(override))
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
# Merge DEFAULTS < _config.yml < override
|
|
117
|
+
Configuration.from(Utils.deep_merge_hashes(config, override)).tap do |obj|
|
|
118
|
+
set_timezone(obj["timezone"]) if obj["timezone"]
|
|
119
|
+
end
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
# Public: Set the TZ environment variable to use the timezone specified
|
|
123
|
+
#
|
|
124
|
+
# timezone - the IANA Time Zone
|
|
125
|
+
#
|
|
126
|
+
# Returns nothing
|
|
127
|
+
# rubocop:disable Naming/AccessorMethodName
|
|
128
|
+
def set_timezone(timezone)
|
|
129
|
+
ENV["TZ"] = if Utils::Platforms.really_windows?
|
|
130
|
+
Utils::WinTZ.calculate(timezone)
|
|
131
|
+
else
|
|
132
|
+
timezone
|
|
133
|
+
end
|
|
134
|
+
end
|
|
135
|
+
# rubocop:enable Naming/AccessorMethodName
|
|
136
|
+
|
|
137
|
+
# Public: Fetch the logger instance for this Jekyll process.
|
|
138
|
+
#
|
|
139
|
+
# Returns the LogAdapter instance.
|
|
140
|
+
def logger
|
|
141
|
+
@logger ||= LogAdapter.new(Stevenson.new, (ENV["JEKYLL_LOG_LEVEL"] || :info).to_sym)
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
# Public: Set the log writer.
|
|
145
|
+
# New log writer must respond to the same methods
|
|
146
|
+
# as Ruby's interal Logger.
|
|
147
|
+
#
|
|
148
|
+
# writer - the new Logger-compatible log transport
|
|
149
|
+
#
|
|
150
|
+
# Returns the new logger.
|
|
151
|
+
def logger=(writer)
|
|
152
|
+
@logger = LogAdapter.new(writer, (ENV["JEKYLL_LOG_LEVEL"] || :info).to_sym)
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
# Public: An array of sites
|
|
156
|
+
#
|
|
157
|
+
# Returns the Jekyll sites created.
|
|
158
|
+
def sites
|
|
159
|
+
@sites ||= []
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
# Public: Ensures the questionable path is prefixed with the base directory
|
|
163
|
+
# and prepends the questionable path with the base directory if false.
|
|
164
|
+
#
|
|
165
|
+
# base_directory - the directory with which to prefix the questionable path
|
|
166
|
+
# questionable_path - the path we're unsure about, and want prefixed
|
|
167
|
+
#
|
|
168
|
+
# Returns the sanitized path.
|
|
169
|
+
def sanitized_path(base_directory, questionable_path)
|
|
170
|
+
return base_directory if base_directory.eql?(questionable_path)
|
|
171
|
+
|
|
172
|
+
clean_path = questionable_path.dup
|
|
173
|
+
clean_path.insert(0, "/") if clean_path.start_with?("~")
|
|
174
|
+
clean_path = File.expand_path(clean_path, "/")
|
|
175
|
+
|
|
176
|
+
return clean_path if clean_path.eql?(base_directory)
|
|
177
|
+
|
|
178
|
+
# remove any remaining extra leading slashes not stripped away by calling
|
|
179
|
+
# `File.expand_path` above.
|
|
180
|
+
clean_path.squeeze!("/")
|
|
181
|
+
|
|
182
|
+
if clean_path.start_with?(base_directory.sub(%r!\z!, "/"))
|
|
183
|
+
clean_path
|
|
184
|
+
else
|
|
185
|
+
clean_path.sub!(%r!\A\w:/!, "/")
|
|
186
|
+
File.join(base_directory, clean_path)
|
|
187
|
+
end
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
# Conditional optimizations
|
|
191
|
+
Jekyll::External.require_if_present("liquid-c")
|
|
192
|
+
end
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
require "jekyll/drops/drop"
|
|
196
|
+
require "jekyll/drops/document_drop"
|
|
197
|
+
require_all "jekyll/commands"
|
|
198
|
+
require_all "jekyll/converters"
|
|
199
|
+
require_all "jekyll/converters/markdown"
|
|
200
|
+
require_all "jekyll/drops"
|
|
201
|
+
require_all "jekyll/generators"
|
|
202
|
+
require_all "jekyll/tags"
|
|
203
|
+
|
|
204
|
+
require "jekyll-sass-converter"
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Jekyll
|
|
4
|
+
# Handles the cleanup of a site's destination before it is built.
|
|
5
|
+
class Cleaner
|
|
6
|
+
HIDDEN_FILE_REGEX = %r!\/\.{1,2}$!
|
|
7
|
+
attr_reader :site
|
|
8
|
+
|
|
9
|
+
def initialize(site)
|
|
10
|
+
@site = site
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
# Cleans up the site's destination directory
|
|
14
|
+
def cleanup!
|
|
15
|
+
FileUtils.rm_rf(obsolete_files)
|
|
16
|
+
FileUtils.rm_rf(metadata_file) unless @site.incremental?
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
private
|
|
20
|
+
|
|
21
|
+
# Private: The list of files and directories to be deleted during cleanup process
|
|
22
|
+
#
|
|
23
|
+
# Returns an Array of the file and directory paths
|
|
24
|
+
def obsolete_files
|
|
25
|
+
out = (existing_files - new_files - new_dirs + replaced_files).to_a
|
|
26
|
+
Jekyll::Hooks.trigger :clean, :on_obsolete, out
|
|
27
|
+
out
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# Private: The metadata file storing dependency tree and build history
|
|
31
|
+
#
|
|
32
|
+
# Returns an Array with the metdata file as the only item
|
|
33
|
+
def metadata_file
|
|
34
|
+
[site.regenerator.metadata_file]
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# Private: The list of existing files, apart from those included in
|
|
38
|
+
# keep_files and hidden files.
|
|
39
|
+
#
|
|
40
|
+
# Returns a Set with the file paths
|
|
41
|
+
def existing_files
|
|
42
|
+
files = Set.new
|
|
43
|
+
regex = keep_file_regex
|
|
44
|
+
dirs = keep_dirs
|
|
45
|
+
|
|
46
|
+
Utils.safe_glob(site.in_dest_dir, ["**", "*"], File::FNM_DOTMATCH).each do |file|
|
|
47
|
+
next if file =~ HIDDEN_FILE_REGEX || file =~ regex || dirs.include?(file)
|
|
48
|
+
|
|
49
|
+
files << file
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
files
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
# Private: The list of files to be created when site is built.
|
|
56
|
+
#
|
|
57
|
+
# Returns a Set with the file paths
|
|
58
|
+
def new_files
|
|
59
|
+
@new_files ||= Set.new.tap do |files|
|
|
60
|
+
site.each_site_file { |item| files << item.destination(site.dest) }
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
# Private: The list of directories to be created when site is built.
|
|
65
|
+
# These are the parent directories of the files in #new_files.
|
|
66
|
+
#
|
|
67
|
+
# Returns a Set with the directory paths
|
|
68
|
+
def new_dirs
|
|
69
|
+
@new_dirs ||= new_files.map { |file| parent_dirs(file) }.flatten.to_set
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
# Private: The list of parent directories of a given file
|
|
73
|
+
#
|
|
74
|
+
# Returns an Array with the directory paths
|
|
75
|
+
def parent_dirs(file)
|
|
76
|
+
parent_dir = File.dirname(file)
|
|
77
|
+
if parent_dir == site.dest
|
|
78
|
+
[]
|
|
79
|
+
else
|
|
80
|
+
[parent_dir] + parent_dirs(parent_dir)
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
# Private: The list of existing files that will be replaced by a directory
|
|
85
|
+
# during build
|
|
86
|
+
#
|
|
87
|
+
# Returns a Set with the file paths
|
|
88
|
+
def replaced_files
|
|
89
|
+
new_dirs.select { |dir| File.file?(dir) }.to_set
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
# Private: The list of directories that need to be kept because they are
|
|
93
|
+
# parent directories of files specified in keep_files
|
|
94
|
+
#
|
|
95
|
+
# Returns a Set with the directory paths
|
|
96
|
+
def keep_dirs
|
|
97
|
+
site.keep_files.map { |file| parent_dirs(site.in_dest_dir(file)) }.flatten.to_set
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
# Private: Creates a regular expression from the config's keep_files array
|
|
101
|
+
#
|
|
102
|
+
# Examples
|
|
103
|
+
# ['.git','.svn'] with site.dest "/myblog/_site" creates
|
|
104
|
+
# the following regex: /\A\/myblog\/_site\/(\.git|\/.svn)/
|
|
105
|
+
#
|
|
106
|
+
# Returns the regular expression
|
|
107
|
+
def keep_file_regex
|
|
108
|
+
%r!\A#{Regexp.quote(site.dest)}\/(#{Regexp.union(site.keep_files).source})!
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
end
|
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Jekyll
|
|
4
|
+
class Collection
|
|
5
|
+
attr_reader :site, :label, :metadata
|
|
6
|
+
attr_writer :docs
|
|
7
|
+
|
|
8
|
+
# Create a new Collection.
|
|
9
|
+
#
|
|
10
|
+
# site - the site to which this collection belongs.
|
|
11
|
+
# label - the name of the collection
|
|
12
|
+
#
|
|
13
|
+
# Returns nothing.
|
|
14
|
+
def initialize(site, label)
|
|
15
|
+
@site = site
|
|
16
|
+
@label = sanitize_label(label)
|
|
17
|
+
@metadata = extract_metadata
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
# Fetch the Documents in this collection.
|
|
21
|
+
# Defaults to an empty array if no documents have been read in.
|
|
22
|
+
#
|
|
23
|
+
# Returns an array of Jekyll::Document objects.
|
|
24
|
+
def docs
|
|
25
|
+
@docs ||= []
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# Override of normal respond_to? to match method_missing's logic for
|
|
29
|
+
# looking in @data.
|
|
30
|
+
def respond_to_missing?(method, include_private = false)
|
|
31
|
+
docs.respond_to?(method.to_sym, include_private) || super
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# Override of method_missing to check in @data for the key.
|
|
35
|
+
def method_missing(method, *args, &blck)
|
|
36
|
+
if docs.respond_to?(method.to_sym)
|
|
37
|
+
Jekyll.logger.warn "Deprecation:",
|
|
38
|
+
"#{label}.#{method} should be changed to #{label}.docs.#{method}."
|
|
39
|
+
Jekyll.logger.warn "", "Called by #{caller(0..0)}."
|
|
40
|
+
docs.public_send(method.to_sym, *args, &blck)
|
|
41
|
+
else
|
|
42
|
+
super
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
# Fetch the static files in this collection.
|
|
47
|
+
# Defaults to an empty array if no static files have been read in.
|
|
48
|
+
#
|
|
49
|
+
# Returns an array of Jekyll::StaticFile objects.
|
|
50
|
+
def files
|
|
51
|
+
@files ||= []
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
# Read the allowed documents into the collection's array of docs.
|
|
55
|
+
#
|
|
56
|
+
# Returns the sorted array of docs.
|
|
57
|
+
def read
|
|
58
|
+
filtered_entries.each do |file_path|
|
|
59
|
+
full_path = collection_dir(file_path)
|
|
60
|
+
next if File.directory?(full_path)
|
|
61
|
+
|
|
62
|
+
if Utils.has_yaml_header? full_path
|
|
63
|
+
read_document(full_path)
|
|
64
|
+
else
|
|
65
|
+
read_static_file(file_path, full_path)
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
docs.sort!
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
# All the entries in this collection.
|
|
72
|
+
#
|
|
73
|
+
# Returns an Array of file paths to the documents in this collection
|
|
74
|
+
# relative to the collection's directory
|
|
75
|
+
def entries
|
|
76
|
+
return [] unless exists?
|
|
77
|
+
|
|
78
|
+
@entries ||=
|
|
79
|
+
Utils.safe_glob(collection_dir, ["**", "*"], File::FNM_DOTMATCH).map do |entry|
|
|
80
|
+
entry["#{collection_dir}/"] = ""
|
|
81
|
+
entry
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
# Filtered version of the entries in this collection.
|
|
86
|
+
# See `Jekyll::EntryFilter#filter` for more information.
|
|
87
|
+
#
|
|
88
|
+
# Returns a list of filtered entry paths.
|
|
89
|
+
def filtered_entries
|
|
90
|
+
return [] unless exists?
|
|
91
|
+
|
|
92
|
+
@filtered_entries ||=
|
|
93
|
+
Dir.chdir(directory) do
|
|
94
|
+
entry_filter.filter(entries).reject do |f|
|
|
95
|
+
path = collection_dir(f)
|
|
96
|
+
File.directory?(path) || entry_filter.symlink?(f)
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
# The directory for this Collection, relative to the site source or the directory
|
|
102
|
+
# containing the collection.
|
|
103
|
+
#
|
|
104
|
+
# Returns a String containing the directory name where the collection
|
|
105
|
+
# is stored on the filesystem.
|
|
106
|
+
def relative_directory
|
|
107
|
+
@relative_directory ||= "_#{label}"
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
# The full path to the directory containing the collection.
|
|
111
|
+
#
|
|
112
|
+
# Returns a String containing th directory name where the collection
|
|
113
|
+
# is stored on the filesystem.
|
|
114
|
+
def directory
|
|
115
|
+
@directory ||= site.in_source_dir(
|
|
116
|
+
File.join(container, relative_directory)
|
|
117
|
+
)
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
# The full path to the directory containing the collection, with
|
|
121
|
+
# optional subpaths.
|
|
122
|
+
#
|
|
123
|
+
# *files - (optional) any other path pieces relative to the
|
|
124
|
+
# directory to append to the path
|
|
125
|
+
#
|
|
126
|
+
# Returns a String containing th directory name where the collection
|
|
127
|
+
# is stored on the filesystem.
|
|
128
|
+
def collection_dir(*files)
|
|
129
|
+
return directory if files.empty?
|
|
130
|
+
|
|
131
|
+
site.in_source_dir(container, relative_directory, *files)
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
# Checks whether the directory "exists" for this collection.
|
|
135
|
+
# The directory must exist on the filesystem and must not be a symlink
|
|
136
|
+
# if in safe mode.
|
|
137
|
+
#
|
|
138
|
+
# Returns false if the directory doesn't exist or if it's a symlink
|
|
139
|
+
# and we're in safe mode.
|
|
140
|
+
def exists?
|
|
141
|
+
File.directory?(directory) && !entry_filter.symlink?(directory)
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
# The entry filter for this collection.
|
|
145
|
+
# Creates an instance of Jekyll::EntryFilter.
|
|
146
|
+
#
|
|
147
|
+
# Returns the instance of Jekyll::EntryFilter for this collection.
|
|
148
|
+
def entry_filter
|
|
149
|
+
@entry_filter ||= Jekyll::EntryFilter.new(site, relative_directory)
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
# An inspect string.
|
|
153
|
+
#
|
|
154
|
+
# Returns the inspect string
|
|
155
|
+
def inspect
|
|
156
|
+
"#<Jekyll::Collection @label=#{label} docs=#{docs}>"
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
# Produce a sanitized label name
|
|
160
|
+
# Label names may not contain anything but alphanumeric characters,
|
|
161
|
+
# underscores, and hyphens.
|
|
162
|
+
#
|
|
163
|
+
# label - the possibly-unsafe label
|
|
164
|
+
#
|
|
165
|
+
# Returns a sanitized version of the label.
|
|
166
|
+
def sanitize_label(label)
|
|
167
|
+
label.gsub(%r![^a-z0-9_\-\.]!i, "")
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
# Produce a representation of this Collection for use in Liquid.
|
|
171
|
+
# Exposes two attributes:
|
|
172
|
+
# - label
|
|
173
|
+
# - docs
|
|
174
|
+
#
|
|
175
|
+
# Returns a representation of this collection for use in Liquid.
|
|
176
|
+
def to_liquid
|
|
177
|
+
Drops::CollectionDrop.new self
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
# Whether the collection's documents ought to be written as individual
|
|
181
|
+
# files in the output.
|
|
182
|
+
#
|
|
183
|
+
# Returns true if the 'write' metadata is true, false otherwise.
|
|
184
|
+
def write?
|
|
185
|
+
!!metadata.fetch("output", false)
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
# The URL template to render collection's documents at.
|
|
189
|
+
#
|
|
190
|
+
# Returns the URL template to render collection's documents at.
|
|
191
|
+
def url_template
|
|
192
|
+
@url_template ||= metadata.fetch("permalink") do
|
|
193
|
+
Utils.add_permalink_suffix("/:collection/:path", site.permalink_style)
|
|
194
|
+
end
|
|
195
|
+
end
|
|
196
|
+
|
|
197
|
+
# Extract options for this collection from the site configuration.
|
|
198
|
+
#
|
|
199
|
+
# Returns the metadata for this collection
|
|
200
|
+
def extract_metadata
|
|
201
|
+
if site.config["collections"].is_a?(Hash)
|
|
202
|
+
site.config["collections"][label] || {}
|
|
203
|
+
else
|
|
204
|
+
{}
|
|
205
|
+
end
|
|
206
|
+
end
|
|
207
|
+
|
|
208
|
+
private
|
|
209
|
+
|
|
210
|
+
def container
|
|
211
|
+
@container ||= site.config["collections_dir"]
|
|
212
|
+
end
|
|
213
|
+
|
|
214
|
+
def read_document(full_path)
|
|
215
|
+
doc = Document.new(full_path, :site => site, :collection => self)
|
|
216
|
+
doc.read
|
|
217
|
+
docs << doc if site.unpublished || doc.published?
|
|
218
|
+
end
|
|
219
|
+
|
|
220
|
+
def read_static_file(file_path, full_path)
|
|
221
|
+
relative_dir = Jekyll.sanitized_path(
|
|
222
|
+
relative_directory,
|
|
223
|
+
File.dirname(file_path)
|
|
224
|
+
).chomp("/.")
|
|
225
|
+
|
|
226
|
+
files << StaticFile.new(
|
|
227
|
+
site,
|
|
228
|
+
site.source,
|
|
229
|
+
relative_dir,
|
|
230
|
+
File.basename(full_path),
|
|
231
|
+
self
|
|
232
|
+
)
|
|
233
|
+
end
|
|
234
|
+
end
|
|
235
|
+
end
|