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
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Jekyll
|
|
4
|
+
class Page
|
|
5
|
+
include Convertible
|
|
6
|
+
|
|
7
|
+
attr_writer :dir
|
|
8
|
+
attr_accessor :site, :pager
|
|
9
|
+
attr_accessor :name, :ext, :basename
|
|
10
|
+
attr_accessor :data, :content, :output
|
|
11
|
+
|
|
12
|
+
alias_method :extname, :ext
|
|
13
|
+
|
|
14
|
+
# Attributes for Liquid templates
|
|
15
|
+
ATTRIBUTES_FOR_LIQUID = %w(
|
|
16
|
+
content
|
|
17
|
+
dir
|
|
18
|
+
name
|
|
19
|
+
path
|
|
20
|
+
url
|
|
21
|
+
).freeze
|
|
22
|
+
|
|
23
|
+
# A set of extensions that are considered HTML or HTML-like so we
|
|
24
|
+
# should not alter them, this includes .xhtml through XHTM5.
|
|
25
|
+
|
|
26
|
+
HTML_EXTENSIONS = %w(
|
|
27
|
+
.html
|
|
28
|
+
.xhtml
|
|
29
|
+
.htm
|
|
30
|
+
).freeze
|
|
31
|
+
|
|
32
|
+
# Initialize a new Page.
|
|
33
|
+
#
|
|
34
|
+
# site - The Site object.
|
|
35
|
+
# base - The String path to the source.
|
|
36
|
+
# dir - The String path between the source and the file.
|
|
37
|
+
# name - The String filename of the file.
|
|
38
|
+
def initialize(site, base, dir, name)
|
|
39
|
+
@site = site
|
|
40
|
+
@base = base
|
|
41
|
+
@dir = dir
|
|
42
|
+
@name = name
|
|
43
|
+
@path = if site.in_theme_dir(base) == base # we're in a theme
|
|
44
|
+
site.in_theme_dir(base, dir, name)
|
|
45
|
+
else
|
|
46
|
+
site.in_source_dir(base, dir, name)
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
process(name)
|
|
50
|
+
read_yaml(File.join(base, dir), name)
|
|
51
|
+
|
|
52
|
+
data.default_proc = proc do |_, key|
|
|
53
|
+
site.frontmatter_defaults.find(File.join(dir, name), type, key)
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
Jekyll::Hooks.trigger :pages, :post_init, self
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
# The generated directory into which the page will be placed
|
|
60
|
+
# upon generation. This is derived from the permalink or, if
|
|
61
|
+
# permalink is absent, will be '/'
|
|
62
|
+
#
|
|
63
|
+
# Returns the String destination directory.
|
|
64
|
+
def dir
|
|
65
|
+
if url.end_with?("/")
|
|
66
|
+
url
|
|
67
|
+
else
|
|
68
|
+
url_dir = File.dirname(url)
|
|
69
|
+
url_dir.end_with?("/") ? url_dir : "#{url_dir}/"
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
# The full path and filename of the post. Defined in the YAML of the post
|
|
74
|
+
# body.
|
|
75
|
+
#
|
|
76
|
+
# Returns the String permalink or nil if none has been set.
|
|
77
|
+
def permalink
|
|
78
|
+
data.nil? ? nil : data["permalink"]
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
# The template of the permalink.
|
|
82
|
+
#
|
|
83
|
+
# Returns the template String.
|
|
84
|
+
def template
|
|
85
|
+
if !html?
|
|
86
|
+
"/:path/:basename:output_ext"
|
|
87
|
+
elsif index?
|
|
88
|
+
"/:path/"
|
|
89
|
+
else
|
|
90
|
+
Utils.add_permalink_suffix("/:path/:basename", site.permalink_style)
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
# The generated relative url of this page. e.g. /about.html.
|
|
95
|
+
#
|
|
96
|
+
# Returns the String url.
|
|
97
|
+
def url
|
|
98
|
+
@url ||= URL.new(
|
|
99
|
+
:template => template,
|
|
100
|
+
:placeholders => url_placeholders,
|
|
101
|
+
:permalink => permalink
|
|
102
|
+
).to_s
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
# Returns a hash of URL placeholder names (as symbols) mapping to the
|
|
106
|
+
# desired placeholder replacements. For details see "url.rb"
|
|
107
|
+
def url_placeholders
|
|
108
|
+
{
|
|
109
|
+
:path => @dir,
|
|
110
|
+
:basename => basename,
|
|
111
|
+
:output_ext => output_ext,
|
|
112
|
+
}
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
# Extract information from the page filename.
|
|
116
|
+
#
|
|
117
|
+
# name - The String filename of the page file.
|
|
118
|
+
#
|
|
119
|
+
# Returns nothing.
|
|
120
|
+
def process(name)
|
|
121
|
+
self.ext = File.extname(name)
|
|
122
|
+
self.basename = name[0..-ext.length - 1]
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
# Add any necessary layouts to this post
|
|
126
|
+
#
|
|
127
|
+
# layouts - The Hash of {"name" => "layout"}.
|
|
128
|
+
# site_payload - The site payload Hash.
|
|
129
|
+
#
|
|
130
|
+
# Returns String rendered page.
|
|
131
|
+
def render(layouts, site_payload)
|
|
132
|
+
site_payload["page"] = to_liquid
|
|
133
|
+
site_payload["paginator"] = pager.to_liquid
|
|
134
|
+
|
|
135
|
+
do_layout(site_payload, layouts)
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
# The path to the source file
|
|
139
|
+
#
|
|
140
|
+
# Returns the path to the source file
|
|
141
|
+
def path
|
|
142
|
+
data.fetch("path") { relative_path }
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
# The path to the page source file, relative to the site source
|
|
146
|
+
def relative_path
|
|
147
|
+
File.join(*[@dir, @name].map(&:to_s).reject(&:empty?)).sub(%r!\A\/!, "")
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
# Obtain destination path.
|
|
151
|
+
#
|
|
152
|
+
# dest - The String path to the destination dir.
|
|
153
|
+
#
|
|
154
|
+
# Returns the destination file path String.
|
|
155
|
+
def destination(dest)
|
|
156
|
+
path = site.in_dest_dir(dest, URL.unescape_path(url))
|
|
157
|
+
path = File.join(path, "index") if url.end_with?("/")
|
|
158
|
+
path << output_ext unless path.end_with? output_ext
|
|
159
|
+
path
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
# Returns the object as a debug String.
|
|
163
|
+
def inspect
|
|
164
|
+
"#<#{self.class} @name=#{name.inspect}>"
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
# Returns the Boolean of whether this Page is HTML or not.
|
|
168
|
+
def html?
|
|
169
|
+
HTML_EXTENSIONS.include?(output_ext)
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
# Returns the Boolean of whether this Page is an index file or not.
|
|
173
|
+
def index?
|
|
174
|
+
basename == "index"
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
def trigger_hooks(hook_name, *args)
|
|
178
|
+
Jekyll::Hooks.trigger :pages, hook_name, self, *args
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
def write?
|
|
182
|
+
true
|
|
183
|
+
end
|
|
184
|
+
end
|
|
185
|
+
end
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Jekyll
|
|
4
|
+
# A Jekyll::Page subclass to handle processing files without reading it to
|
|
5
|
+
# determine the page-data and page-content based on Front Matter delimiters.
|
|
6
|
+
#
|
|
7
|
+
# The class instance is basically just a bare-bones entity with just
|
|
8
|
+
# attributes "dir", "name", "path", "url" defined on it.
|
|
9
|
+
class PageWithoutAFile < Page
|
|
10
|
+
def read_yaml(*)
|
|
11
|
+
@data ||= {}
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Jekyll
|
|
4
|
+
class Plugin
|
|
5
|
+
PRIORITIES = {
|
|
6
|
+
:low => -10,
|
|
7
|
+
:highest => 100,
|
|
8
|
+
:lowest => -100,
|
|
9
|
+
:normal => 0,
|
|
10
|
+
:high => 10,
|
|
11
|
+
}.freeze
|
|
12
|
+
|
|
13
|
+
#
|
|
14
|
+
|
|
15
|
+
def self.inherited(const)
|
|
16
|
+
catch_inheritance(const) do |const_|
|
|
17
|
+
catch_inheritance(const_)
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
#
|
|
22
|
+
|
|
23
|
+
def self.catch_inheritance(const)
|
|
24
|
+
const.define_singleton_method :inherited do |const_|
|
|
25
|
+
(@children ||= Set.new).add const_
|
|
26
|
+
yield const_ if block_given?
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
#
|
|
31
|
+
|
|
32
|
+
def self.descendants
|
|
33
|
+
@children ||= Set.new
|
|
34
|
+
out = @children.map(&:descendants)
|
|
35
|
+
out << self unless superclass == Plugin
|
|
36
|
+
Set.new(out).flatten
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# Get or set the priority of this plugin. When called without an
|
|
40
|
+
# argument it returns the priority. When an argument is given, it will
|
|
41
|
+
# set the priority.
|
|
42
|
+
#
|
|
43
|
+
# priority - The Symbol priority (default: nil). Valid options are:
|
|
44
|
+
# :lowest, :low, :normal, :high, :highest
|
|
45
|
+
#
|
|
46
|
+
# Returns the Symbol priority.
|
|
47
|
+
def self.priority(priority = nil)
|
|
48
|
+
@priority ||= nil
|
|
49
|
+
@priority = priority if priority && PRIORITIES.key?(priority)
|
|
50
|
+
@priority || :normal
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
# Get or set the safety of this plugin. When called without an argument
|
|
54
|
+
# it returns the safety. When an argument is given, it will set the
|
|
55
|
+
# safety.
|
|
56
|
+
#
|
|
57
|
+
# safe - The Boolean safety (default: nil).
|
|
58
|
+
#
|
|
59
|
+
# Returns the safety Boolean.
|
|
60
|
+
def self.safe(safe = nil)
|
|
61
|
+
@safe = safe unless defined?(@safe) && safe.nil?
|
|
62
|
+
@safe || false
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
# Spaceship is priority [higher -> lower]
|
|
66
|
+
#
|
|
67
|
+
# other - The class to be compared.
|
|
68
|
+
#
|
|
69
|
+
# Returns -1, 0, 1.
|
|
70
|
+
def self.<=>(other)
|
|
71
|
+
PRIORITIES[other.priority] <=> PRIORITIES[priority]
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
# Spaceship is priority [higher -> lower]
|
|
75
|
+
#
|
|
76
|
+
# other - The class to be compared.
|
|
77
|
+
#
|
|
78
|
+
# Returns -1, 0, 1.
|
|
79
|
+
def <=>(other)
|
|
80
|
+
self.class <=> other.class
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
# Initialize a new plugin. This should be overridden by the subclass.
|
|
84
|
+
#
|
|
85
|
+
# config - The Hash of configuration options.
|
|
86
|
+
#
|
|
87
|
+
# Returns a new instance.
|
|
88
|
+
def initialize(config = {})
|
|
89
|
+
# no-op for default
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
end
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Jekyll
|
|
4
|
+
class PluginManager
|
|
5
|
+
attr_reader :site
|
|
6
|
+
|
|
7
|
+
# Create an instance of this class.
|
|
8
|
+
#
|
|
9
|
+
# site - the instance of Jekyll::Site we're concerned with
|
|
10
|
+
#
|
|
11
|
+
# Returns nothing
|
|
12
|
+
def initialize(site)
|
|
13
|
+
@site = site
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
# Require all the plugins which are allowed.
|
|
17
|
+
#
|
|
18
|
+
# Returns nothing
|
|
19
|
+
def conscientious_require
|
|
20
|
+
require_theme_deps if site.theme
|
|
21
|
+
require_plugin_files
|
|
22
|
+
require_gems
|
|
23
|
+
deprecation_checks
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# Require each of the gem plugins specified.
|
|
27
|
+
#
|
|
28
|
+
# Returns nothing.
|
|
29
|
+
def require_gems
|
|
30
|
+
Jekyll::External.require_with_graceful_fail(
|
|
31
|
+
site.gems.select { |plugin| plugin_allowed?(plugin) }
|
|
32
|
+
)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
# Require each of the runtime_dependencies specified by the theme's gemspec.
|
|
36
|
+
#
|
|
37
|
+
# Returns false only if no dependencies have been specified, otherwise nothing.
|
|
38
|
+
def require_theme_deps
|
|
39
|
+
return false unless site.theme.runtime_dependencies
|
|
40
|
+
|
|
41
|
+
site.theme.runtime_dependencies.each do |dep|
|
|
42
|
+
next if dep.name == "jekyll"
|
|
43
|
+
|
|
44
|
+
External.require_with_graceful_fail(dep.name) if plugin_allowed?(dep.name)
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def self.require_from_bundler
|
|
49
|
+
if !ENV["JEKYLL_NO_BUNDLER_REQUIRE"] && File.file?("Gemfile")
|
|
50
|
+
require "bundler"
|
|
51
|
+
|
|
52
|
+
Bundler.setup
|
|
53
|
+
required_gems = Bundler.require(:jekyll_plugins)
|
|
54
|
+
message = "Required #{required_gems.map(&:name).join(", ")}"
|
|
55
|
+
Jekyll.logger.debug("PluginManager:", message)
|
|
56
|
+
ENV["JEKYLL_NO_BUNDLER_REQUIRE"] = "true"
|
|
57
|
+
|
|
58
|
+
true
|
|
59
|
+
else
|
|
60
|
+
false
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
# Check whether a gem plugin is allowed to be used during this build.
|
|
65
|
+
#
|
|
66
|
+
# plugin_name - the name of the plugin
|
|
67
|
+
#
|
|
68
|
+
# Returns true if the plugin name is in the whitelist or if the site is not
|
|
69
|
+
# in safe mode.
|
|
70
|
+
def plugin_allowed?(plugin_name)
|
|
71
|
+
!site.safe || whitelist.include?(plugin_name)
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
# Build an array of allowed plugin gem names.
|
|
75
|
+
#
|
|
76
|
+
# Returns an array of strings, each string being the name of a gem name
|
|
77
|
+
# that is allowed to be used.
|
|
78
|
+
def whitelist
|
|
79
|
+
@whitelist ||= Array[site.config["whitelist"]].flatten
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
# Require all .rb files if safe mode is off
|
|
83
|
+
#
|
|
84
|
+
# Returns nothing.
|
|
85
|
+
def require_plugin_files
|
|
86
|
+
unless site.safe
|
|
87
|
+
plugins_path.each do |plugin_search_path|
|
|
88
|
+
plugin_files = Utils.safe_glob(plugin_search_path, File.join("**", "*.rb"))
|
|
89
|
+
Jekyll::External.require_with_graceful_fail(plugin_files)
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
# Public: Setup the plugin search path
|
|
95
|
+
#
|
|
96
|
+
# Returns an Array of plugin search paths
|
|
97
|
+
def plugins_path
|
|
98
|
+
if site.config["plugins_dir"].eql? Jekyll::Configuration::DEFAULTS["plugins_dir"]
|
|
99
|
+
[site.in_source_dir(site.config["plugins_dir"])]
|
|
100
|
+
else
|
|
101
|
+
Array(site.config["plugins_dir"]).map { |d| File.expand_path(d) }
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
def deprecation_checks
|
|
106
|
+
pagination_included = (site.config["plugins"] || []).include?("jekyll-paginate") ||
|
|
107
|
+
defined?(Jekyll::Paginate)
|
|
108
|
+
if site.config["paginate"] && !pagination_included
|
|
109
|
+
Jekyll::Deprecator.deprecation_message "You appear to have pagination " \
|
|
110
|
+
"turned on, but you haven't included the `jekyll-paginate` gem. " \
|
|
111
|
+
"Ensure you have `plugins: [jekyll-paginate]` in your configuration file."
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Jekyll
|
|
4
|
+
class Publisher
|
|
5
|
+
def initialize(site)
|
|
6
|
+
@site = site
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def publish?(thing)
|
|
10
|
+
can_be_published?(thing) && !hidden_in_the_future?(thing)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def hidden_in_the_future?(thing)
|
|
14
|
+
thing.respond_to?(:date) && !@site.future && thing.date.to_i > @site.time.to_i
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
private
|
|
18
|
+
|
|
19
|
+
def can_be_published?(thing)
|
|
20
|
+
thing.data.fetch("published", true) || @site.unpublished
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Jekyll
|
|
4
|
+
class Reader
|
|
5
|
+
attr_reader :site
|
|
6
|
+
|
|
7
|
+
def initialize(site)
|
|
8
|
+
@site = site
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
# Read Site data from disk and load it into internal data structures.
|
|
12
|
+
#
|
|
13
|
+
# Returns nothing.
|
|
14
|
+
def read
|
|
15
|
+
@site.layouts = LayoutReader.new(site).read
|
|
16
|
+
read_directories
|
|
17
|
+
sort_files!
|
|
18
|
+
@site.data = DataReader.new(site).read(site.config["data_dir"])
|
|
19
|
+
CollectionReader.new(site).read
|
|
20
|
+
ThemeAssetsReader.new(site).read
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
# Sorts posts, pages, and static files.
|
|
24
|
+
def sort_files!
|
|
25
|
+
site.collections.each_value { |c| c.docs.sort! }
|
|
26
|
+
site.pages.sort_by!(&:name)
|
|
27
|
+
site.static_files.sort_by!(&:relative_path)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# Recursively traverse directories to find pages and static files
|
|
31
|
+
# that will become part of the site according to the rules in
|
|
32
|
+
# filter_entries.
|
|
33
|
+
#
|
|
34
|
+
# dir - The String relative path of the directory to read. Default: ''.
|
|
35
|
+
#
|
|
36
|
+
# Returns nothing.
|
|
37
|
+
def read_directories(dir = "")
|
|
38
|
+
base = site.in_source_dir(dir)
|
|
39
|
+
|
|
40
|
+
return unless File.directory?(base)
|
|
41
|
+
|
|
42
|
+
dot = Dir.chdir(base) { filter_entries(Dir.entries("."), base) }
|
|
43
|
+
dot_dirs = dot.select { |file| File.directory?(@site.in_source_dir(base, file)) }
|
|
44
|
+
dot_files = (dot - dot_dirs)
|
|
45
|
+
dot_pages = dot_files.select do |file|
|
|
46
|
+
Utils.has_yaml_header?(@site.in_source_dir(base, file))
|
|
47
|
+
end
|
|
48
|
+
dot_static_files = dot_files - dot_pages
|
|
49
|
+
|
|
50
|
+
retrieve_posts(dir)
|
|
51
|
+
retrieve_dirs(base, dir, dot_dirs)
|
|
52
|
+
retrieve_pages(dir, dot_pages)
|
|
53
|
+
retrieve_static_files(dir, dot_static_files)
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
# Retrieves all the posts(posts/drafts) from the given directory
|
|
57
|
+
# and add them to the site and sort them.
|
|
58
|
+
#
|
|
59
|
+
# dir - The String representing the directory to retrieve the posts from.
|
|
60
|
+
#
|
|
61
|
+
# Returns nothing.
|
|
62
|
+
def retrieve_posts(dir)
|
|
63
|
+
return if outside_configured_directory?(dir)
|
|
64
|
+
|
|
65
|
+
site.posts.docs.concat(post_reader.read_posts(dir))
|
|
66
|
+
site.posts.docs.concat(post_reader.read_drafts(dir)) if site.show_drafts
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
# Recursively traverse directories with the read_directories function.
|
|
70
|
+
#
|
|
71
|
+
# base - The String representing the site's base directory.
|
|
72
|
+
# dir - The String representing the directory to traverse down.
|
|
73
|
+
# dot_dirs - The Array of subdirectories in the dir.
|
|
74
|
+
#
|
|
75
|
+
# Returns nothing.
|
|
76
|
+
def retrieve_dirs(_base, dir, dot_dirs)
|
|
77
|
+
dot_dirs.each do |file|
|
|
78
|
+
dir_path = site.in_source_dir(dir, file)
|
|
79
|
+
rel_path = File.join(dir, file)
|
|
80
|
+
@site.reader.read_directories(rel_path) unless @site.dest.chomp("/") == dir_path
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
# Retrieve all the pages from the current directory,
|
|
85
|
+
# add them to the site and sort them.
|
|
86
|
+
#
|
|
87
|
+
# dir - The String representing the directory retrieve the pages from.
|
|
88
|
+
# dot_pages - The Array of pages in the dir.
|
|
89
|
+
#
|
|
90
|
+
# Returns nothing.
|
|
91
|
+
def retrieve_pages(dir, dot_pages)
|
|
92
|
+
site.pages.concat(PageReader.new(site, dir).read(dot_pages))
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
# Retrieve all the static files from the current directory,
|
|
96
|
+
# add them to the site and sort them.
|
|
97
|
+
#
|
|
98
|
+
# dir - The directory retrieve the static files from.
|
|
99
|
+
# dot_static_files - The static files in the dir.
|
|
100
|
+
#
|
|
101
|
+
# Returns nothing.
|
|
102
|
+
def retrieve_static_files(dir, dot_static_files)
|
|
103
|
+
site.static_files.concat(StaticFileReader.new(site, dir).read(dot_static_files))
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
# Filter out any files/directories that are hidden or backup files (start
|
|
107
|
+
# with "." or "#" or end with "~"), or contain site content (start with "_"),
|
|
108
|
+
# or are excluded in the site configuration, unless they are web server
|
|
109
|
+
# files such as '.htaccess'.
|
|
110
|
+
#
|
|
111
|
+
# entries - The Array of String file/directory entries to filter.
|
|
112
|
+
# base_directory - The string representing the optional base directory.
|
|
113
|
+
#
|
|
114
|
+
# Returns the Array of filtered entries.
|
|
115
|
+
def filter_entries(entries, base_directory = nil)
|
|
116
|
+
EntryFilter.new(site, base_directory).filter(entries)
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
# Read the entries from a particular directory for processing
|
|
120
|
+
#
|
|
121
|
+
# dir - The String representing the relative path of the directory to read.
|
|
122
|
+
# subfolder - The String representing the directory to read.
|
|
123
|
+
#
|
|
124
|
+
# Returns the list of entries to process
|
|
125
|
+
def get_entries(dir, subfolder)
|
|
126
|
+
base = site.in_source_dir(dir, subfolder)
|
|
127
|
+
return [] unless File.exist?(base)
|
|
128
|
+
|
|
129
|
+
entries = Dir.chdir(base) { filter_entries(Dir["**/*"], base) }
|
|
130
|
+
entries.delete_if { |e| File.directory?(site.in_source_dir(base, e)) }
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
private
|
|
134
|
+
|
|
135
|
+
# Internal
|
|
136
|
+
#
|
|
137
|
+
# Determine if the directory is supposed to contain posts and drafts.
|
|
138
|
+
# If the user has defined a custom collections_dir, then attempt to read
|
|
139
|
+
# posts and drafts only from within that directory.
|
|
140
|
+
#
|
|
141
|
+
# Returns true if a custom collections_dir has been set but current directory lies
|
|
142
|
+
# outside that directory.
|
|
143
|
+
def outside_configured_directory?(dir)
|
|
144
|
+
collections_dir = site.config["collections_dir"]
|
|
145
|
+
!collections_dir.empty? && !dir.start_with?("/#{collections_dir}")
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
# Create a single PostReader instance to retrieve drafts and posts from all valid
|
|
149
|
+
# directories in current site.
|
|
150
|
+
def post_reader
|
|
151
|
+
@post_reader ||= PostReader.new(site)
|
|
152
|
+
end
|
|
153
|
+
end
|
|
154
|
+
end
|