mirror of
https://github.com/bitwarden/help
synced 2025-12-24 04:04:27 +00:00
Promote to Master (#748)
* initial commit
* adding quotes for the array error
* Create Gemfile
* Create Gemfile.lock
* add .nvmrc and .node-version
* removed /article from URL
* update links to work with netlify
* more fixed links
* link fixes
* update bad links
* Update netlify.toml
toml test for redirects
* article redirect
* link fixes
* Update index.html
* Update netlify.toml
* Update _config.yml
* Update netlify.toml
* Update netlify.toml
* Update netlify.toml
* Update netlify.toml
* Update netlify.toml
* add article back into URL for launch
* Update netlify.toml
* Update netlify.toml
* add order to categories front matter
* Update netlify.toml
* update
* sidemenu update
* Revert "sidemenu update"
This reverts commit 5441c3d35c.
* update order prop
* Navbar updates per Gary and compiler warnings
* font/style tweaks
* Update sidebar.html
* Stage Release Documentation (#739)
* initial drafts
* rewrite Custom Fields article to prioritize new context-menu option & better organize ancillary information
* edit
* edit
* Custom Field Context Menu & CAPTCHA item in release notes
* SSO relink event
* update rn
* small edits
* improve release notes titles
* fix side menu
* Edits courtest of mportune!
* update order
* link fixes
* link cleanup
* image updates and a link
* fix trailing slash
Co-authored-by: DanHillesheim <79476558+DanHillesheim@users.noreply.github.com>
This commit is contained in:
committed by
GitHub
parent
63f78e8979
commit
906e2ca0dd
190
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/cache.rb
vendored
Normal file
190
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/cache.rb
vendored
Normal file
@@ -0,0 +1,190 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "digest"
|
||||
|
||||
module Jekyll
|
||||
class Cache
|
||||
# class-wide base cache
|
||||
@base_cache = {}
|
||||
|
||||
# class-wide directive to write cache to disk is enabled by default
|
||||
@disk_cache_enabled = true
|
||||
|
||||
class << self
|
||||
# class-wide cache location
|
||||
attr_accessor :cache_dir
|
||||
|
||||
# class-wide directive to write cache to disk
|
||||
attr_reader :disk_cache_enabled
|
||||
|
||||
# class-wide base cache reader
|
||||
attr_reader :base_cache
|
||||
|
||||
# Disable Marshaling cached items to disk
|
||||
def disable_disk_cache!
|
||||
@disk_cache_enabled = false
|
||||
end
|
||||
|
||||
# Clear all caches
|
||||
def clear
|
||||
delete_cache_files
|
||||
base_cache.each_value(&:clear)
|
||||
end
|
||||
|
||||
# Compare the current config to the cached config
|
||||
# If they are different, clear all caches
|
||||
#
|
||||
# Returns nothing.
|
||||
def clear_if_config_changed(config)
|
||||
config = config.inspect
|
||||
cache = Jekyll::Cache.new "Jekyll::Cache"
|
||||
return if cache.key?("config") && cache["config"] == config
|
||||
|
||||
clear
|
||||
cache = Jekyll::Cache.new "Jekyll::Cache"
|
||||
cache["config"] = config
|
||||
nil
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# Delete all cached items from all caches
|
||||
#
|
||||
# Returns nothing.
|
||||
def delete_cache_files
|
||||
FileUtils.rm_rf(@cache_dir) if disk_cache_enabled
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
|
||||
# Get an existing named cache, or create a new one if none exists
|
||||
#
|
||||
# name - name of the cache
|
||||
#
|
||||
# Returns nothing.
|
||||
def initialize(name)
|
||||
@cache = Jekyll::Cache.base_cache[name] ||= {}
|
||||
@name = name.gsub(%r![^\w\s-]!, "-")
|
||||
end
|
||||
|
||||
# Clear this particular cache
|
||||
def clear
|
||||
delete_cache_files
|
||||
@cache.clear
|
||||
end
|
||||
|
||||
# Retrieve a cached item
|
||||
# Raises if key does not exist in cache
|
||||
#
|
||||
# Returns cached value
|
||||
def [](key)
|
||||
return @cache[key] if @cache.key?(key)
|
||||
|
||||
path = path_to(hash(key))
|
||||
if disk_cache_enabled? && File.file?(path) && File.readable?(path)
|
||||
@cache[key] = load(path)
|
||||
else
|
||||
raise
|
||||
end
|
||||
end
|
||||
|
||||
# Add an item to cache
|
||||
#
|
||||
# Returns nothing.
|
||||
def []=(key, value)
|
||||
@cache[key] = value
|
||||
return unless disk_cache_enabled?
|
||||
|
||||
path = path_to(hash(key))
|
||||
value = new Hash(value) if value.is_a?(Hash) && !value.default.nil?
|
||||
dump(path, value)
|
||||
rescue TypeError
|
||||
Jekyll.logger.debug "Cache:", "Cannot dump object #{key}"
|
||||
end
|
||||
|
||||
# If an item already exists in the cache, retrieve it.
|
||||
# Else execute code block, and add the result to the cache, and return that result.
|
||||
def getset(key)
|
||||
self[key]
|
||||
rescue StandardError
|
||||
value = yield
|
||||
self[key] = value
|
||||
value
|
||||
end
|
||||
|
||||
# Remove one particular item from the cache
|
||||
#
|
||||
# Returns nothing.
|
||||
def delete(key)
|
||||
@cache.delete(key)
|
||||
File.delete(path_to(hash(key))) if disk_cache_enabled?
|
||||
end
|
||||
|
||||
# Check if `key` already exists in this cache
|
||||
#
|
||||
# Returns true if key exists in the cache, false otherwise
|
||||
def key?(key)
|
||||
# First, check if item is already cached in memory
|
||||
return true if @cache.key?(key)
|
||||
# Otherwise, it might be cached on disk
|
||||
# but we should not consider the disk cache if it is disabled
|
||||
return false unless disk_cache_enabled?
|
||||
|
||||
path = path_to(hash(key))
|
||||
File.file?(path) && File.readable?(path)
|
||||
end
|
||||
|
||||
def disk_cache_enabled?
|
||||
!!Jekyll::Cache.disk_cache_enabled
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# Given a hashed key, return the path to where this item would be saved on disk.
|
||||
def path_to(hash = nil)
|
||||
@base_dir ||= File.join(Jekyll::Cache.cache_dir, @name)
|
||||
return @base_dir if hash.nil?
|
||||
|
||||
File.join(@base_dir, hash[0..1], hash[2..-1]).freeze
|
||||
end
|
||||
|
||||
# Given a key, return a SHA2 hash that can be used for caching this item to disk.
|
||||
def hash(key)
|
||||
Digest::SHA2.hexdigest(key).freeze
|
||||
end
|
||||
|
||||
# Remove all this caches items from disk
|
||||
#
|
||||
# Returns nothing.
|
||||
def delete_cache_files
|
||||
FileUtils.rm_rf(path_to) if disk_cache_enabled?
|
||||
end
|
||||
|
||||
# Load `path` from disk and return the result.
|
||||
# This MUST NEVER be called in Safe Mode
|
||||
# rubocop:disable Security/MarshalLoad
|
||||
def load(path)
|
||||
raise unless disk_cache_enabled?
|
||||
|
||||
cached_file = File.open(path, "rb")
|
||||
value = Marshal.load(cached_file)
|
||||
cached_file.close
|
||||
value
|
||||
end
|
||||
# rubocop:enable Security/MarshalLoad
|
||||
|
||||
# Given a path and a value, save value to disk at path.
|
||||
# This should NEVER be called in Safe Mode
|
||||
#
|
||||
# Returns nothing.
|
||||
def dump(path, value)
|
||||
return unless disk_cache_enabled?
|
||||
|
||||
FileUtils.mkdir_p(File.dirname(path))
|
||||
File.open(path, "wb") do |cached_file|
|
||||
Marshal.dump(value, cached_file)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
111
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/cleaner.rb
vendored
Normal file
111
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/cleaner.rb
vendored
Normal file
@@ -0,0 +1,111 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Jekyll
|
||||
# Handles the cleanup of a site's destination before it is built.
|
||||
class Cleaner
|
||||
HIDDEN_FILE_REGEX = %r!/\.{1,2}$!.freeze
|
||||
attr_reader :site
|
||||
|
||||
def initialize(site)
|
||||
@site = site
|
||||
end
|
||||
|
||||
# Cleans up the site's destination directory
|
||||
def cleanup!
|
||||
FileUtils.rm_rf(obsolete_files)
|
||||
FileUtils.rm_rf(metadata_file) unless @site.incremental?
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# Private: The list of files and directories to be deleted during cleanup process
|
||||
#
|
||||
# Returns an Array of the file and directory paths
|
||||
def obsolete_files
|
||||
out = (existing_files - new_files - new_dirs + replaced_files).to_a
|
||||
Jekyll::Hooks.trigger :clean, :on_obsolete, out
|
||||
out
|
||||
end
|
||||
|
||||
# Private: The metadata file storing dependency tree and build history
|
||||
#
|
||||
# Returns an Array with the metdata file as the only item
|
||||
def metadata_file
|
||||
[site.regenerator.metadata_file]
|
||||
end
|
||||
|
||||
# Private: The list of existing files, apart from those included in
|
||||
# keep_files and hidden files.
|
||||
#
|
||||
# Returns a Set with the file paths
|
||||
def existing_files
|
||||
files = Set.new
|
||||
regex = keep_file_regex
|
||||
dirs = keep_dirs
|
||||
|
||||
Utils.safe_glob(site.in_dest_dir, ["**", "*"], File::FNM_DOTMATCH).each do |file|
|
||||
next if HIDDEN_FILE_REGEX.match?(file) || regex.match?(file) || dirs.include?(file)
|
||||
|
||||
files << file
|
||||
end
|
||||
|
||||
files
|
||||
end
|
||||
|
||||
# Private: The list of files to be created when site is built.
|
||||
#
|
||||
# Returns a Set with the file paths
|
||||
def new_files
|
||||
@new_files ||= Set.new.tap do |files|
|
||||
site.each_site_file { |item| files << item.destination(site.dest) }
|
||||
end
|
||||
end
|
||||
|
||||
# Private: The list of directories to be created when site is built.
|
||||
# These are the parent directories of the files in #new_files.
|
||||
#
|
||||
# Returns a Set with the directory paths
|
||||
def new_dirs
|
||||
@new_dirs ||= new_files.flat_map { |file| parent_dirs(file) }.to_set
|
||||
end
|
||||
|
||||
# Private: The list of parent directories of a given file
|
||||
#
|
||||
# Returns an Array with the directory paths
|
||||
def parent_dirs(file)
|
||||
parent_dir = File.dirname(file)
|
||||
if parent_dir == site.dest
|
||||
[]
|
||||
else
|
||||
parent_dirs(parent_dir).unshift(parent_dir)
|
||||
end
|
||||
end
|
||||
|
||||
# Private: The list of existing files that will be replaced by a directory
|
||||
# during build
|
||||
#
|
||||
# Returns a Set with the file paths
|
||||
def replaced_files
|
||||
new_dirs.select { |dir| File.file?(dir) }.to_set
|
||||
end
|
||||
|
||||
# Private: The list of directories that need to be kept because they are
|
||||
# parent directories of files specified in keep_files
|
||||
#
|
||||
# Returns a Set with the directory paths
|
||||
def keep_dirs
|
||||
site.keep_files.flat_map { |file| parent_dirs(site.in_dest_dir(file)) }.to_set
|
||||
end
|
||||
|
||||
# Private: Creates a regular expression from the config's keep_files array
|
||||
#
|
||||
# Examples
|
||||
# ['.git','.svn'] with site.dest "/myblog/_site" creates
|
||||
# the following regex: /\A\/myblog\/_site\/(\.git|\/.svn)/
|
||||
#
|
||||
# Returns the regular expression
|
||||
def keep_file_regex
|
||||
%r!\A#{Regexp.quote(site.dest)}/(#{Regexp.union(site.keep_files).source})!
|
||||
end
|
||||
end
|
||||
end
|
||||
309
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/collection.rb
vendored
Normal file
309
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/collection.rb
vendored
Normal file
@@ -0,0 +1,309 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Jekyll
|
||||
class Collection
|
||||
attr_reader :site, :label, :metadata
|
||||
attr_writer :docs
|
||||
|
||||
# Create a new Collection.
|
||||
#
|
||||
# site - the site to which this collection belongs.
|
||||
# label - the name of the collection
|
||||
#
|
||||
# Returns nothing.
|
||||
def initialize(site, label)
|
||||
@site = site
|
||||
@label = sanitize_label(label)
|
||||
@metadata = extract_metadata
|
||||
end
|
||||
|
||||
# Fetch the Documents in this collection.
|
||||
# Defaults to an empty array if no documents have been read in.
|
||||
#
|
||||
# Returns an array of Jekyll::Document objects.
|
||||
def docs
|
||||
@docs ||= []
|
||||
end
|
||||
|
||||
# Override of normal respond_to? to match method_missing's logic for
|
||||
# looking in @data.
|
||||
def respond_to_missing?(method, include_private = false)
|
||||
docs.respond_to?(method.to_sym, include_private) || super
|
||||
end
|
||||
|
||||
# Override of method_missing to check in @data for the key.
|
||||
def method_missing(method, *args, &blck)
|
||||
if docs.respond_to?(method.to_sym)
|
||||
Jekyll.logger.warn "Deprecation:",
|
||||
"#{label}.#{method} should be changed to #{label}.docs.#{method}."
|
||||
Jekyll.logger.warn "", "Called by #{caller(0..0)}."
|
||||
docs.public_send(method.to_sym, *args, &blck)
|
||||
else
|
||||
super
|
||||
end
|
||||
end
|
||||
|
||||
# Fetch the static files in this collection.
|
||||
# Defaults to an empty array if no static files have been read in.
|
||||
#
|
||||
# Returns an array of Jekyll::StaticFile objects.
|
||||
def files
|
||||
@files ||= []
|
||||
end
|
||||
|
||||
# Read the allowed documents into the collection's array of docs.
|
||||
#
|
||||
# Returns the sorted array of docs.
|
||||
def read
|
||||
filtered_entries.each do |file_path|
|
||||
full_path = collection_dir(file_path)
|
||||
next if File.directory?(full_path)
|
||||
|
||||
if Utils.has_yaml_header? full_path
|
||||
read_document(full_path)
|
||||
else
|
||||
read_static_file(file_path, full_path)
|
||||
end
|
||||
end
|
||||
sort_docs!
|
||||
end
|
||||
|
||||
# All the entries in this collection.
|
||||
#
|
||||
# Returns an Array of file paths to the documents in this collection
|
||||
# relative to the collection's directory
|
||||
def entries
|
||||
return [] unless exists?
|
||||
|
||||
@entries ||= begin
|
||||
collection_dir_slash = "#{collection_dir}/"
|
||||
Utils.safe_glob(collection_dir, ["**", "*"], File::FNM_DOTMATCH).map do |entry|
|
||||
entry[collection_dir_slash] = ""
|
||||
entry
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Filtered version of the entries in this collection.
|
||||
# See `Jekyll::EntryFilter#filter` for more information.
|
||||
#
|
||||
# Returns a list of filtered entry paths.
|
||||
def filtered_entries
|
||||
return [] unless exists?
|
||||
|
||||
@filtered_entries ||=
|
||||
Dir.chdir(directory) do
|
||||
entry_filter.filter(entries).reject do |f|
|
||||
path = collection_dir(f)
|
||||
File.directory?(path) || entry_filter.symlink?(f)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# The directory for this Collection, relative to the site source or the directory
|
||||
# containing the collection.
|
||||
#
|
||||
# Returns a String containing the directory name where the collection
|
||||
# is stored on the filesystem.
|
||||
def relative_directory
|
||||
@relative_directory ||= "_#{label}"
|
||||
end
|
||||
|
||||
# The full path to the directory containing the collection.
|
||||
#
|
||||
# Returns a String containing th directory name where the collection
|
||||
# is stored on the filesystem.
|
||||
def directory
|
||||
@directory ||= site.in_source_dir(
|
||||
File.join(container, relative_directory)
|
||||
)
|
||||
end
|
||||
|
||||
# The full path to the directory containing the collection, with
|
||||
# optional subpaths.
|
||||
#
|
||||
# *files - (optional) any other path pieces relative to the
|
||||
# directory to append to the path
|
||||
#
|
||||
# Returns a String containing th directory name where the collection
|
||||
# is stored on the filesystem.
|
||||
def collection_dir(*files)
|
||||
return directory if files.empty?
|
||||
|
||||
site.in_source_dir(container, relative_directory, *files)
|
||||
end
|
||||
|
||||
# Checks whether the directory "exists" for this collection.
|
||||
# The directory must exist on the filesystem and must not be a symlink
|
||||
# if in safe mode.
|
||||
#
|
||||
# Returns false if the directory doesn't exist or if it's a symlink
|
||||
# and we're in safe mode.
|
||||
def exists?
|
||||
File.directory?(directory) && !entry_filter.symlink?(directory)
|
||||
end
|
||||
|
||||
# The entry filter for this collection.
|
||||
# Creates an instance of Jekyll::EntryFilter.
|
||||
#
|
||||
# Returns the instance of Jekyll::EntryFilter for this collection.
|
||||
def entry_filter
|
||||
@entry_filter ||= Jekyll::EntryFilter.new(site, relative_directory)
|
||||
end
|
||||
|
||||
# An inspect string.
|
||||
#
|
||||
# Returns the inspect string
|
||||
def inspect
|
||||
"#<#{self.class} @label=#{label} docs=#{docs}>"
|
||||
end
|
||||
|
||||
# Produce a sanitized label name
|
||||
# Label names may not contain anything but alphanumeric characters,
|
||||
# underscores, and hyphens.
|
||||
#
|
||||
# label - the possibly-unsafe label
|
||||
#
|
||||
# Returns a sanitized version of the label.
|
||||
def sanitize_label(label)
|
||||
label.gsub(%r![^a-z0-9_\-.]!i, "")
|
||||
end
|
||||
|
||||
# Produce a representation of this Collection for use in Liquid.
|
||||
# Exposes two attributes:
|
||||
# - label
|
||||
# - docs
|
||||
#
|
||||
# Returns a representation of this collection for use in Liquid.
|
||||
def to_liquid
|
||||
Drops::CollectionDrop.new self
|
||||
end
|
||||
|
||||
# Whether the collection's documents ought to be written as individual
|
||||
# files in the output.
|
||||
#
|
||||
# Returns true if the 'write' metadata is true, false otherwise.
|
||||
def write?
|
||||
!!metadata.fetch("output", false)
|
||||
end
|
||||
|
||||
# The URL template to render collection's documents at.
|
||||
#
|
||||
# Returns the URL template to render collection's documents at.
|
||||
def url_template
|
||||
@url_template ||= metadata.fetch("permalink") do
|
||||
Utils.add_permalink_suffix("/:collection/:path", site.permalink_style)
|
||||
end
|
||||
end
|
||||
|
||||
# Extract options for this collection from the site configuration.
|
||||
#
|
||||
# Returns the metadata for this collection
|
||||
def extract_metadata
|
||||
if site.config["collections"].is_a?(Hash)
|
||||
site.config["collections"][label] || {}
|
||||
else
|
||||
{}
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def container
|
||||
@container ||= site.config["collections_dir"]
|
||||
end
|
||||
|
||||
def read_document(full_path)
|
||||
doc = Document.new(full_path, :site => site, :collection => self)
|
||||
doc.read
|
||||
docs << doc if site.unpublished || doc.published?
|
||||
end
|
||||
|
||||
def sort_docs!
|
||||
if metadata["order"].is_a?(Array)
|
||||
rearrange_docs!
|
||||
elsif metadata["sort_by"].is_a?(String)
|
||||
sort_docs_by_key!
|
||||
else
|
||||
docs.sort!
|
||||
end
|
||||
end
|
||||
|
||||
# A custom sort function based on Schwartzian transform
|
||||
# Refer https://byparker.com/blog/2017/schwartzian-transform-faster-sorting/ for details
|
||||
def sort_docs_by_key!
|
||||
meta_key = metadata["sort_by"]
|
||||
# Modify `docs` array to cache document's property along with the Document instance
|
||||
docs.map! { |doc| [doc.data[meta_key], doc] }.sort! do |apples, olives|
|
||||
order = determine_sort_order(meta_key, apples, olives)
|
||||
|
||||
# Fall back to `Document#<=>` if the properties were equal or were non-sortable
|
||||
# Otherwise continue with current sort-order
|
||||
if order.nil? || order.zero?
|
||||
apples[-1] <=> olives[-1]
|
||||
else
|
||||
order
|
||||
end
|
||||
|
||||
# Finally restore the `docs` array with just the Document objects themselves
|
||||
end.map!(&:last)
|
||||
end
|
||||
|
||||
def determine_sort_order(sort_key, apples, olives)
|
||||
apple_property, apple_document = apples
|
||||
olive_property, olive_document = olives
|
||||
|
||||
if apple_property.nil? && !olive_property.nil?
|
||||
order_with_warning(sort_key, apple_document, 1)
|
||||
elsif !apple_property.nil? && olive_property.nil?
|
||||
order_with_warning(sort_key, olive_document, -1)
|
||||
else
|
||||
apple_property <=> olive_property
|
||||
end
|
||||
end
|
||||
|
||||
def order_with_warning(sort_key, document, order)
|
||||
Jekyll.logger.warn "Sort warning:", "'#{sort_key}' not defined in #{document.relative_path}"
|
||||
order
|
||||
end
|
||||
|
||||
# Rearrange documents within the `docs` array as listed in the `metadata["order"]` array.
|
||||
#
|
||||
# Involves converting the two arrays into hashes based on relative_paths as keys first, then
|
||||
# merging them to remove duplicates and finally retrieving the Document instances from the
|
||||
# merged array.
|
||||
def rearrange_docs!
|
||||
docs_table = {}
|
||||
custom_order = {}
|
||||
|
||||
# pre-sort to normalize default array across platforms and then proceed to create a Hash
|
||||
# from that sorted array.
|
||||
docs.sort.each do |doc|
|
||||
docs_table[doc.relative_path] = doc
|
||||
end
|
||||
|
||||
metadata["order"].each do |entry|
|
||||
custom_order[File.join(relative_directory, entry)] = nil
|
||||
end
|
||||
|
||||
result = Jekyll::Utils.deep_merge_hashes(custom_order, docs_table).values
|
||||
result.compact!
|
||||
self.docs = result
|
||||
end
|
||||
|
||||
def read_static_file(file_path, full_path)
|
||||
relative_dir = Jekyll.sanitized_path(
|
||||
relative_directory,
|
||||
File.dirname(file_path)
|
||||
).chomp("/.")
|
||||
|
||||
files << StaticFile.new(
|
||||
site,
|
||||
site.source,
|
||||
relative_dir,
|
||||
File.basename(full_path),
|
||||
self
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
105
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/command.rb
vendored
Normal file
105
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/command.rb
vendored
Normal file
@@ -0,0 +1,105 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Jekyll
|
||||
class Command
|
||||
class << self
|
||||
# A list of subclasses of Jekyll::Command
|
||||
def subclasses
|
||||
@subclasses ||= []
|
||||
end
|
||||
|
||||
# Keep a list of subclasses of Jekyll::Command every time it's inherited
|
||||
# Called automatically.
|
||||
#
|
||||
# base - the subclass
|
||||
#
|
||||
# Returns nothing
|
||||
def inherited(base)
|
||||
subclasses << base
|
||||
super(base)
|
||||
end
|
||||
|
||||
# Run Site#process and catch errors
|
||||
#
|
||||
# site - the Jekyll::Site object
|
||||
#
|
||||
# Returns nothing
|
||||
def process_site(site)
|
||||
site.process
|
||||
rescue Jekyll::Errors::FatalException => e
|
||||
Jekyll.logger.error "ERROR:", "YOUR SITE COULD NOT BE BUILT:"
|
||||
Jekyll.logger.error "", "------------------------------------"
|
||||
Jekyll.logger.error "", e.message
|
||||
exit(1)
|
||||
end
|
||||
|
||||
# Create a full Jekyll configuration with the options passed in as overrides
|
||||
#
|
||||
# options - the configuration overrides
|
||||
#
|
||||
# Returns a full Jekyll configuration
|
||||
def configuration_from_options(options)
|
||||
return options if options.is_a?(Jekyll::Configuration)
|
||||
|
||||
Jekyll.configuration(options)
|
||||
end
|
||||
|
||||
# Add common options to a command for building configuration
|
||||
#
|
||||
# cmd - the Jekyll::Command to add these options to
|
||||
#
|
||||
# Returns nothing
|
||||
# rubocop:disable Metrics/MethodLength
|
||||
def add_build_options(cmd)
|
||||
cmd.option "config", "--config CONFIG_FILE[,CONFIG_FILE2,...]",
|
||||
Array, "Custom configuration file"
|
||||
cmd.option "destination", "-d", "--destination DESTINATION",
|
||||
"The current folder will be generated into DESTINATION"
|
||||
cmd.option "source", "-s", "--source SOURCE", "Custom source directory"
|
||||
cmd.option "future", "--future", "Publishes posts with a future date"
|
||||
cmd.option "limit_posts", "--limit_posts MAX_POSTS", Integer,
|
||||
"Limits the number of posts to parse and publish"
|
||||
cmd.option "watch", "-w", "--[no-]watch", "Watch for changes and rebuild"
|
||||
cmd.option "baseurl", "-b", "--baseurl URL",
|
||||
"Serve the website from the given base URL"
|
||||
cmd.option "force_polling", "--force_polling", "Force watch to use polling"
|
||||
cmd.option "lsi", "--lsi", "Use LSI for improved related posts"
|
||||
cmd.option "show_drafts", "-D", "--drafts", "Render posts in the _drafts folder"
|
||||
cmd.option "unpublished", "--unpublished",
|
||||
"Render posts that were marked as unpublished"
|
||||
cmd.option "disable_disk_cache", "--disable-disk-cache",
|
||||
"Disable caching to disk in non-safe mode"
|
||||
cmd.option "quiet", "-q", "--quiet", "Silence output."
|
||||
cmd.option "verbose", "-V", "--verbose", "Print verbose output."
|
||||
cmd.option "incremental", "-I", "--incremental", "Enable incremental rebuild."
|
||||
cmd.option "strict_front_matter", "--strict_front_matter",
|
||||
"Fail if errors are present in front matter"
|
||||
end
|
||||
# rubocop:enable Metrics/MethodLength
|
||||
|
||||
# Run ::process method in a given set of Jekyll::Command subclasses and suggest
|
||||
# re-running the associated command with --trace switch to obtain any additional
|
||||
# information or backtrace regarding the encountered Exception.
|
||||
#
|
||||
# cmd - the Jekyll::Command to be handled
|
||||
# options - configuration overrides
|
||||
# klass - an array of Jekyll::Command subclasses associated with the command
|
||||
#
|
||||
# Note that all exceptions are rescued..
|
||||
# rubocop: disable Lint/RescueException
|
||||
def process_with_graceful_fail(cmd, options, *klass)
|
||||
klass.each { |k| k.process(options) if k.respond_to?(:process) }
|
||||
rescue Exception => e
|
||||
raise e if cmd.trace
|
||||
|
||||
msg = " Please append `--trace` to the `#{cmd.name}` command "
|
||||
dashes = "-" * msg.length
|
||||
Jekyll.logger.error "", dashes
|
||||
Jekyll.logger.error "Jekyll #{Jekyll::VERSION} ", msg
|
||||
Jekyll.logger.error "", " for any additional information or backtrace. "
|
||||
Jekyll.logger.abort_with "", dashes
|
||||
end
|
||||
# rubocop: enable Lint/RescueException
|
||||
end
|
||||
end
|
||||
end
|
||||
93
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/commands/build.rb
vendored
Normal file
93
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/commands/build.rb
vendored
Normal file
@@ -0,0 +1,93 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Jekyll
|
||||
module Commands
|
||||
class Build < Command
|
||||
class << self
|
||||
# Create the Mercenary command for the Jekyll CLI for this Command
|
||||
def init_with_program(prog)
|
||||
prog.command(:build) do |c|
|
||||
c.syntax "build [options]"
|
||||
c.description "Build your site"
|
||||
c.alias :b
|
||||
|
||||
add_build_options(c)
|
||||
|
||||
c.action do |_, options|
|
||||
options["serving"] = false
|
||||
process_with_graceful_fail(c, options, self)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Build your jekyll site
|
||||
# Continuously watch if `watch` is set to true in the config.
|
||||
def process(options)
|
||||
# Adjust verbosity quickly
|
||||
Jekyll.logger.adjust_verbosity(options)
|
||||
|
||||
options = configuration_from_options(options)
|
||||
site = Jekyll::Site.new(options)
|
||||
|
||||
if options.fetch("skip_initial_build", false)
|
||||
Jekyll.logger.warn "Build Warning:", "Skipping the initial build." \
|
||||
" This may result in an out-of-date site."
|
||||
else
|
||||
build(site, options)
|
||||
end
|
||||
|
||||
if options.fetch("detach", false)
|
||||
Jekyll.logger.info "Auto-regeneration:",
|
||||
"disabled when running server detached."
|
||||
elsif options.fetch("watch", false)
|
||||
watch(site, options)
|
||||
else
|
||||
Jekyll.logger.info "Auto-regeneration:", "disabled. Use --watch to enable."
|
||||
end
|
||||
end
|
||||
|
||||
# Build your Jekyll site.
|
||||
#
|
||||
# site - the Jekyll::Site instance to build
|
||||
# options - A Hash of options passed to the command
|
||||
#
|
||||
# Returns nothing.
|
||||
def build(site, options)
|
||||
t = Time.now
|
||||
source = File.expand_path(options["source"])
|
||||
destination = File.expand_path(options["destination"])
|
||||
incremental = options["incremental"]
|
||||
Jekyll.logger.info "Source:", source
|
||||
Jekyll.logger.info "Destination:", destination
|
||||
Jekyll.logger.info "Incremental build:",
|
||||
(incremental ? "enabled" : "disabled. Enable with --incremental")
|
||||
Jekyll.logger.info "Generating..."
|
||||
process_site(site)
|
||||
Jekyll.logger.info "", "done in #{(Time.now - t).round(3)} seconds."
|
||||
end
|
||||
|
||||
# Private: Watch for file changes and rebuild the site.
|
||||
#
|
||||
# site - A Jekyll::Site instance
|
||||
# options - A Hash of options passed to the command
|
||||
#
|
||||
# Returns nothing.
|
||||
def watch(site, options)
|
||||
# Warn Windows users that they might need to upgrade.
|
||||
if Utils::Platforms.bash_on_windows?
|
||||
Jekyll.logger.warn "",
|
||||
"Auto-regeneration may not work on some Windows versions."
|
||||
Jekyll.logger.warn "",
|
||||
"Please see: https://github.com/Microsoft/BashOnWindows/issues/216"
|
||||
Jekyll.logger.warn "",
|
||||
"If it does not work, please upgrade Bash on Windows or "\
|
||||
"run Jekyll with --no-watch."
|
||||
end
|
||||
|
||||
External.require_with_graceful_fail "jekyll-watch"
|
||||
Jekyll::Watcher.watch(options, site)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
45
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/commands/clean.rb
vendored
Normal file
45
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/commands/clean.rb
vendored
Normal file
@@ -0,0 +1,45 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Jekyll
|
||||
module Commands
|
||||
class Clean < Command
|
||||
class << self
|
||||
def init_with_program(prog)
|
||||
prog.command(:clean) do |c|
|
||||
c.syntax "clean [subcommand]"
|
||||
c.description "Clean the site " \
|
||||
"(removes site output and metadata file) without building."
|
||||
|
||||
add_build_options(c)
|
||||
|
||||
c.action do |_, options|
|
||||
Jekyll::Commands::Clean.process(options)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def process(options)
|
||||
options = configuration_from_options(options)
|
||||
destination = options["destination"]
|
||||
metadata_file = File.join(options["source"], ".jekyll-metadata")
|
||||
cache_dir = File.join(options["source"], options["cache_dir"])
|
||||
sass_cache = ".sass-cache"
|
||||
|
||||
remove(destination, :checker_func => :directory?)
|
||||
remove(metadata_file, :checker_func => :file?)
|
||||
remove(cache_dir, :checker_func => :directory?)
|
||||
remove(sass_cache, :checker_func => :directory?)
|
||||
end
|
||||
|
||||
def remove(filename, checker_func: :file?)
|
||||
if File.public_send(checker_func, filename)
|
||||
Jekyll.logger.info "Cleaner:", "Removing #{filename}..."
|
||||
FileUtils.rm_rf(filename)
|
||||
else
|
||||
Jekyll.logger.info "Cleaner:", "Nothing to do for #{filename}."
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
177
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/commands/doctor.rb
vendored
Normal file
177
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/commands/doctor.rb
vendored
Normal file
@@ -0,0 +1,177 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Jekyll
|
||||
module Commands
|
||||
class Doctor < Command
|
||||
class << self
|
||||
def init_with_program(prog)
|
||||
prog.command(:doctor) do |c|
|
||||
c.syntax "doctor"
|
||||
c.description "Search site and print specific deprecation warnings"
|
||||
c.alias(:hyde)
|
||||
|
||||
c.option "config", "--config CONFIG_FILE[,CONFIG_FILE2,...]", Array,
|
||||
"Custom configuration file"
|
||||
|
||||
c.action do |_, options|
|
||||
Jekyll::Commands::Doctor.process(options)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def process(options)
|
||||
site = Jekyll::Site.new(configuration_from_options(options))
|
||||
site.reset
|
||||
site.read
|
||||
site.generate
|
||||
|
||||
if healthy?(site)
|
||||
Jekyll.logger.info "Your test results", "are in. Everything looks fine."
|
||||
else
|
||||
abort
|
||||
end
|
||||
end
|
||||
|
||||
def healthy?(site)
|
||||
[
|
||||
fsnotify_buggy?(site),
|
||||
!deprecated_relative_permalinks(site),
|
||||
!conflicting_urls(site),
|
||||
!urls_only_differ_by_case(site),
|
||||
proper_site_url?(site),
|
||||
properly_gathered_posts?(site),
|
||||
].all?
|
||||
end
|
||||
|
||||
def properly_gathered_posts?(site)
|
||||
return true if site.config["collections_dir"].empty?
|
||||
|
||||
posts_at_root = site.in_source_dir("_posts")
|
||||
return true unless File.directory?(posts_at_root)
|
||||
|
||||
Jekyll.logger.warn "Warning:",
|
||||
"Detected '_posts' directory outside custom `collections_dir`!"
|
||||
Jekyll.logger.warn "",
|
||||
"Please move '#{posts_at_root}' into the custom directory at " \
|
||||
"'#{site.in_source_dir(site.config["collections_dir"])}'"
|
||||
false
|
||||
end
|
||||
|
||||
def deprecated_relative_permalinks(site)
|
||||
if site.config["relative_permalinks"]
|
||||
Jekyll::Deprecator.deprecation_message "Your site still uses relative permalinks," \
|
||||
" which was removed in Jekyll v3.0.0."
|
||||
true
|
||||
end
|
||||
end
|
||||
|
||||
def conflicting_urls(site)
|
||||
conflicting_urls = false
|
||||
destination_map(site).each do |dest, paths|
|
||||
next unless paths.size > 1
|
||||
|
||||
conflicting_urls = true
|
||||
Jekyll.logger.warn "Conflict:",
|
||||
"The following destination is shared by multiple files."
|
||||
Jekyll.logger.warn "", "The written file may end up with unexpected contents."
|
||||
Jekyll.logger.warn "", dest.to_s.cyan
|
||||
paths.each { |path| Jekyll.logger.warn "", " - #{path}" }
|
||||
Jekyll.logger.warn ""
|
||||
end
|
||||
conflicting_urls
|
||||
end
|
||||
|
||||
def fsnotify_buggy?(_site)
|
||||
return true unless Utils::Platforms.osx?
|
||||
|
||||
if Dir.pwd != `pwd`.strip
|
||||
Jekyll.logger.error <<~STR
|
||||
We have detected that there might be trouble using fsevent on your
|
||||
operating system, you can read https://github.com/thibaudgg/rb-fsevent/wiki/no-fsevents-fired-(OSX-bug)
|
||||
for possible work arounds or you can work around it immediately
|
||||
with `--force-polling`.
|
||||
STR
|
||||
|
||||
false
|
||||
end
|
||||
|
||||
true
|
||||
end
|
||||
|
||||
def urls_only_differ_by_case(site)
|
||||
urls_only_differ_by_case = false
|
||||
urls = case_insensitive_urls(site.pages + site.docs_to_write, site.dest)
|
||||
urls.each_value do |real_urls|
|
||||
next unless real_urls.uniq.size > 1
|
||||
|
||||
urls_only_differ_by_case = true
|
||||
Jekyll.logger.warn "Warning:", "The following URLs only differ" \
|
||||
" by case. On a case-insensitive file system one of the URLs" \
|
||||
" will be overwritten by the other: #{real_urls.join(", ")}"
|
||||
end
|
||||
urls_only_differ_by_case
|
||||
end
|
||||
|
||||
def proper_site_url?(site)
|
||||
url = site.config["url"]
|
||||
[
|
||||
url_exists?(url),
|
||||
url_valid?(url),
|
||||
url_absolute(url),
|
||||
].all?
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def destination_map(site)
|
||||
{}.tap do |result|
|
||||
site.each_site_file do |thing|
|
||||
next if allow_used_permalink?(thing)
|
||||
|
||||
dest_path = thing.destination(site.dest)
|
||||
(result[dest_path] ||= []) << thing.path
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def allow_used_permalink?(item)
|
||||
defined?(JekyllRedirectFrom) && item.is_a?(JekyllRedirectFrom::RedirectPage)
|
||||
end
|
||||
|
||||
def case_insensitive_urls(things, destination)
|
||||
things.each_with_object({}) do |thing, memo|
|
||||
dest = thing.destination(destination)
|
||||
(memo[dest.downcase] ||= []) << dest
|
||||
end
|
||||
end
|
||||
|
||||
def url_exists?(url)
|
||||
return true unless url.nil? || url.empty?
|
||||
|
||||
Jekyll.logger.warn "Warning:", "You didn't set an URL in the config file, "\
|
||||
"you may encounter problems with some plugins."
|
||||
false
|
||||
end
|
||||
|
||||
def url_valid?(url)
|
||||
Addressable::URI.parse(url)
|
||||
true
|
||||
# Addressable::URI#parse only raises a TypeError
|
||||
# https://git.io/vFfbx
|
||||
rescue TypeError
|
||||
Jekyll.logger.warn "Warning:", "The site URL does not seem to be valid, "\
|
||||
"check the value of `url` in your config file."
|
||||
false
|
||||
end
|
||||
|
||||
def url_absolute(url)
|
||||
return true if url.is_a?(String) && Addressable::URI.parse(url).absolute?
|
||||
|
||||
Jekyll.logger.warn "Warning:", "Your site URL does not seem to be absolute, "\
|
||||
"check the value of `url` in your config file."
|
||||
false
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
34
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/commands/help.rb
vendored
Normal file
34
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/commands/help.rb
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Jekyll
|
||||
module Commands
|
||||
class Help < Command
|
||||
class << self
|
||||
def init_with_program(prog)
|
||||
prog.command(:help) do |c|
|
||||
c.syntax "help [subcommand]"
|
||||
c.description "Show the help message, optionally for a given subcommand."
|
||||
|
||||
c.action do |args, _|
|
||||
cmd = (args.first || "").to_sym
|
||||
if args.empty?
|
||||
Jekyll.logger.info prog.to_s
|
||||
elsif prog.has_command? cmd
|
||||
Jekyll.logger.info prog.commands[cmd].to_s
|
||||
else
|
||||
invalid_command(prog, cmd)
|
||||
abort
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def invalid_command(prog, cmd)
|
||||
Jekyll.logger.error "Error:",
|
||||
"Hmm... we don't know what the '#{cmd}' command is."
|
||||
Jekyll.logger.info "Valid commands:", prog.commands.keys.join(", ")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
169
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/commands/new.rb
vendored
Normal file
169
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/commands/new.rb
vendored
Normal file
@@ -0,0 +1,169 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "erb"
|
||||
|
||||
module Jekyll
|
||||
module Commands
|
||||
class New < Command
|
||||
class << self
|
||||
def init_with_program(prog)
|
||||
prog.command(:new) do |c|
|
||||
c.syntax "new PATH"
|
||||
c.description "Creates a new Jekyll site scaffold in PATH"
|
||||
|
||||
c.option "force", "--force", "Force creation even if PATH already exists"
|
||||
c.option "blank", "--blank", "Creates scaffolding but with empty files"
|
||||
c.option "skip-bundle", "--skip-bundle", "Skip 'bundle install'"
|
||||
|
||||
c.action do |args, options|
|
||||
Jekyll::Commands::New.process(args, options)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def process(args, options = {})
|
||||
raise ArgumentError, "You must specify a path." if args.empty?
|
||||
|
||||
new_blog_path = File.expand_path(args.join(" "), Dir.pwd)
|
||||
FileUtils.mkdir_p new_blog_path
|
||||
if preserve_source_location?(new_blog_path, options)
|
||||
Jekyll.logger.error "Conflict:", "#{new_blog_path} exists and is not empty."
|
||||
Jekyll.logger.abort_with "", "Ensure #{new_blog_path} is empty or else " \
|
||||
"try again with `--force` to proceed and overwrite any files."
|
||||
end
|
||||
|
||||
if options["blank"]
|
||||
create_blank_site new_blog_path
|
||||
else
|
||||
create_site new_blog_path
|
||||
end
|
||||
|
||||
after_install(new_blog_path, options)
|
||||
end
|
||||
|
||||
def blank_template
|
||||
File.expand_path("../../blank_template", __dir__)
|
||||
end
|
||||
|
||||
def create_blank_site(path)
|
||||
FileUtils.cp_r blank_template + "/.", path
|
||||
FileUtils.chmod_R "u+w", path
|
||||
|
||||
Dir.chdir(path) do
|
||||
FileUtils.mkdir(%w(_data _drafts _includes _posts))
|
||||
end
|
||||
end
|
||||
|
||||
def scaffold_post_content
|
||||
ERB.new(File.read(File.expand_path(scaffold_path, site_template))).result
|
||||
end
|
||||
|
||||
# Internal: Gets the filename of the sample post to be created
|
||||
#
|
||||
# Returns the filename of the sample post, as a String
|
||||
def initialized_post_name
|
||||
"_posts/#{Time.now.strftime("%Y-%m-%d")}-welcome-to-jekyll.markdown"
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def gemfile_contents
|
||||
<<~RUBY
|
||||
source "https://rubygems.org"
|
||||
# Hello! This is where you manage which Jekyll version is used to run.
|
||||
# When you want to use a different version, change it below, save the
|
||||
# file and run `bundle install`. Run Jekyll with `bundle exec`, like so:
|
||||
#
|
||||
# bundle exec jekyll serve
|
||||
#
|
||||
# This will help ensure the proper Jekyll version is running.
|
||||
# Happy Jekylling!
|
||||
gem "jekyll", "~> #{Jekyll::VERSION}"
|
||||
# This is the default theme for new Jekyll sites. You may change this to anything you like.
|
||||
gem "minima", "~> 2.5"
|
||||
# If you want to use GitHub Pages, remove the "gem "jekyll"" above and
|
||||
# uncomment the line below. To upgrade, run `bundle update github-pages`.
|
||||
# gem "github-pages", group: :jekyll_plugins
|
||||
# If you have any plugins, put them here!
|
||||
group :jekyll_plugins do
|
||||
gem "jekyll-feed", "~> 0.12"
|
||||
end
|
||||
|
||||
# Windows and JRuby does not include zoneinfo files, so bundle the tzinfo-data gem
|
||||
# and associated library.
|
||||
platforms :mingw, :x64_mingw, :mswin, :jruby do
|
||||
gem "tzinfo", "~> 1.2"
|
||||
gem "tzinfo-data"
|
||||
end
|
||||
|
||||
# Performance-booster for watching directories on Windows
|
||||
gem "wdm", "~> 0.1.1", :platforms => [:mingw, :x64_mingw, :mswin]
|
||||
|
||||
RUBY
|
||||
end
|
||||
|
||||
def create_site(new_blog_path)
|
||||
create_sample_files new_blog_path
|
||||
|
||||
File.open(File.expand_path(initialized_post_name, new_blog_path), "w") do |f|
|
||||
f.write(scaffold_post_content)
|
||||
end
|
||||
|
||||
File.open(File.expand_path("Gemfile", new_blog_path), "w") do |f|
|
||||
f.write(gemfile_contents)
|
||||
end
|
||||
end
|
||||
|
||||
def preserve_source_location?(path, options)
|
||||
!options["force"] && !Dir["#{path}/**/*"].empty?
|
||||
end
|
||||
|
||||
def create_sample_files(path)
|
||||
FileUtils.cp_r site_template + "/.", path
|
||||
FileUtils.chmod_R "u+w", path
|
||||
FileUtils.rm File.expand_path(scaffold_path, path)
|
||||
end
|
||||
|
||||
def site_template
|
||||
File.expand_path("../../site_template", __dir__)
|
||||
end
|
||||
|
||||
def scaffold_path
|
||||
"_posts/0000-00-00-welcome-to-jekyll.markdown.erb"
|
||||
end
|
||||
|
||||
# After a new blog has been created, print a success notification and
|
||||
# then automatically execute bundle install from within the new blog dir
|
||||
# unless the user opts to generate a blank blog or skip 'bundle install'.
|
||||
|
||||
def after_install(path, options = {})
|
||||
unless options["blank"] || options["skip-bundle"]
|
||||
begin
|
||||
require "bundler"
|
||||
bundle_install path
|
||||
rescue LoadError
|
||||
Jekyll.logger.info "Could not load Bundler. Bundle install skipped."
|
||||
end
|
||||
end
|
||||
|
||||
Jekyll.logger.info "New jekyll site installed in #{path.cyan}."
|
||||
Jekyll.logger.info "Bundle install skipped." if options["skip-bundle"]
|
||||
end
|
||||
|
||||
def bundle_install(path)
|
||||
Jekyll.logger.info "Running bundle install in #{path.cyan}..."
|
||||
Dir.chdir(path) do
|
||||
exe = Gem.bin_path("bundler", "bundle")
|
||||
process, output = Jekyll::Utils::Exec.run("ruby", exe, "install")
|
||||
|
||||
output.to_s.each_line do |line|
|
||||
Jekyll.logger.info("Bundler:".green, line.strip) unless line.to_s.empty?
|
||||
end
|
||||
|
||||
raise SystemExit unless process.success?
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
40
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/commands/new_theme.rb
vendored
Normal file
40
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/commands/new_theme.rb
vendored
Normal file
@@ -0,0 +1,40 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "erb"
|
||||
|
||||
module Jekyll
|
||||
module Commands
|
||||
class NewTheme < Jekyll::Command
|
||||
class << self
|
||||
def init_with_program(prog)
|
||||
prog.command(:"new-theme") do |c|
|
||||
c.syntax "new-theme NAME"
|
||||
c.description "Creates a new Jekyll theme scaffold"
|
||||
c.option "code_of_conduct", \
|
||||
"-c", "--code-of-conduct", \
|
||||
"Include a Code of Conduct. (defaults to false)"
|
||||
|
||||
c.action do |args, opts|
|
||||
Jekyll::Commands::NewTheme.process(args, opts)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def process(args, opts)
|
||||
if !args || args.empty?
|
||||
raise Jekyll::Errors::InvalidThemeName, "You must specify a theme name."
|
||||
end
|
||||
|
||||
new_theme_name = args.join("_")
|
||||
theme = Jekyll::ThemeBuilder.new(new_theme_name, opts)
|
||||
Jekyll.logger.abort_with "Conflict:", "#{theme.path} already exists." if theme.path.exist?
|
||||
|
||||
theme.create!
|
||||
Jekyll.logger.info "Your new Jekyll theme, #{theme.name.cyan}," \
|
||||
" is ready for you in #{theme.path.to_s.cyan}!"
|
||||
Jekyll.logger.info "For help getting started, read #{theme.path}/README.md."
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
365
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/commands/serve.rb
vendored
Normal file
365
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/commands/serve.rb
vendored
Normal file
@@ -0,0 +1,365 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Jekyll
|
||||
module Commands
|
||||
class Serve < Command
|
||||
# Similar to the pattern in Utils::ThreadEvent except we are maintaining the
|
||||
# state of @running instead of just signaling an event. We have to maintain this
|
||||
# state since Serve is just called via class methods instead of an instance
|
||||
# being created each time.
|
||||
@mutex = Mutex.new
|
||||
@run_cond = ConditionVariable.new
|
||||
@running = false
|
||||
|
||||
class << self
|
||||
COMMAND_OPTIONS = {
|
||||
"ssl_cert" => ["--ssl-cert [CERT]", "X.509 (SSL) certificate."],
|
||||
"host" => ["host", "-H", "--host [HOST]", "Host to bind to"],
|
||||
"open_url" => ["-o", "--open-url", "Launch your site in a browser"],
|
||||
"detach" => ["-B", "--detach",
|
||||
"Run the server in the background",],
|
||||
"ssl_key" => ["--ssl-key [KEY]", "X.509 (SSL) Private Key."],
|
||||
"port" => ["-P", "--port [PORT]", "Port to listen on"],
|
||||
"show_dir_listing" => ["--show-dir-listing",
|
||||
"Show a directory listing instead of loading" \
|
||||
" your index file.",],
|
||||
"skip_initial_build" => ["skip_initial_build", "--skip-initial-build",
|
||||
"Skips the initial site build which occurs before" \
|
||||
" the server is started.",],
|
||||
"livereload" => ["-l", "--livereload",
|
||||
"Use LiveReload to automatically refresh browsers",],
|
||||
"livereload_ignore" => ["--livereload-ignore ignore GLOB1[,GLOB2[,...]]",
|
||||
Array,
|
||||
"Files for LiveReload to ignore. " \
|
||||
"Remember to quote the values so your shell " \
|
||||
"won't expand them",],
|
||||
"livereload_min_delay" => ["--livereload-min-delay [SECONDS]",
|
||||
"Minimum reload delay",],
|
||||
"livereload_max_delay" => ["--livereload-max-delay [SECONDS]",
|
||||
"Maximum reload delay",],
|
||||
"livereload_port" => ["--livereload-port [PORT]", Integer,
|
||||
"Port for LiveReload to listen on",],
|
||||
}.freeze
|
||||
|
||||
DIRECTORY_INDEX = %w(
|
||||
index.htm
|
||||
index.html
|
||||
index.rhtml
|
||||
index.xht
|
||||
index.xhtml
|
||||
index.cgi
|
||||
index.xml
|
||||
index.json
|
||||
).freeze
|
||||
|
||||
LIVERELOAD_PORT = 35_729
|
||||
LIVERELOAD_DIR = File.join(__dir__, "serve", "livereload_assets")
|
||||
|
||||
attr_reader :mutex, :run_cond, :running
|
||||
alias_method :running?, :running
|
||||
|
||||
def init_with_program(prog)
|
||||
prog.command(:serve) do |cmd|
|
||||
cmd.description "Serve your site locally"
|
||||
cmd.syntax "serve [options]"
|
||||
cmd.alias :server
|
||||
cmd.alias :s
|
||||
|
||||
add_build_options(cmd)
|
||||
COMMAND_OPTIONS.each do |key, val|
|
||||
cmd.option key, *val
|
||||
end
|
||||
|
||||
cmd.action do |_, opts|
|
||||
opts["livereload_port"] ||= LIVERELOAD_PORT
|
||||
opts["serving"] = true
|
||||
opts["watch"] = true unless opts.key?("watch")
|
||||
|
||||
# Set the reactor to nil so any old reactor will be GCed.
|
||||
# We can't unregister a hook so while running tests we don't want to
|
||||
# inadvertently keep using a reactor created by a previous test.
|
||||
@reload_reactor = nil
|
||||
|
||||
config = configuration_from_options(opts)
|
||||
config["url"] = default_url(config) if Jekyll.env == "development"
|
||||
|
||||
process_with_graceful_fail(cmd, config, Build, Serve)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
|
||||
def process(opts)
|
||||
opts = configuration_from_options(opts)
|
||||
destination = opts["destination"]
|
||||
if opts["livereload"]
|
||||
validate_options(opts)
|
||||
register_reload_hooks(opts)
|
||||
end
|
||||
setup(destination)
|
||||
|
||||
start_up_webrick(opts, destination)
|
||||
end
|
||||
|
||||
def shutdown
|
||||
@server.shutdown if running?
|
||||
end
|
||||
|
||||
# Perform logical validation of CLI options
|
||||
|
||||
private
|
||||
|
||||
def validate_options(opts)
|
||||
if opts["livereload"]
|
||||
if opts["detach"]
|
||||
Jekyll.logger.warn "Warning:", "--detach and --livereload are mutually exclusive." \
|
||||
" Choosing --livereload"
|
||||
opts["detach"] = false
|
||||
end
|
||||
if opts["ssl_cert"] || opts["ssl_key"]
|
||||
# This is not technically true. LiveReload works fine over SSL, but
|
||||
# EventMachine's SSL support in Windows requires building the gem's
|
||||
# native extensions against OpenSSL and that proved to be a process
|
||||
# so tedious that expecting users to do it is a non-starter.
|
||||
Jekyll.logger.abort_with "Error:", "LiveReload does not support SSL"
|
||||
end
|
||||
unless opts["watch"]
|
||||
# Using livereload logically implies you want to watch the files
|
||||
opts["watch"] = true
|
||||
end
|
||||
elsif %w(livereload_min_delay
|
||||
livereload_max_delay
|
||||
livereload_ignore
|
||||
livereload_port).any? { |o| opts[o] }
|
||||
Jekyll.logger.abort_with "--livereload-min-delay, "\
|
||||
"--livereload-max-delay, --livereload-ignore, and "\
|
||||
"--livereload-port require the --livereload option."
|
||||
end
|
||||
end
|
||||
|
||||
# rubocop:disable Metrics/AbcSize
|
||||
def register_reload_hooks(opts)
|
||||
require_relative "serve/live_reload_reactor"
|
||||
@reload_reactor = LiveReloadReactor.new
|
||||
|
||||
Jekyll::Hooks.register(:site, :post_render) do |site|
|
||||
regenerator = Jekyll::Regenerator.new(site)
|
||||
@changed_pages = site.pages.select do |p|
|
||||
regenerator.regenerate?(p)
|
||||
end
|
||||
end
|
||||
|
||||
# A note on ignoring files: LiveReload errs on the side of reloading when it
|
||||
# comes to the message it gets. If, for example, a page is ignored but a CSS
|
||||
# file linked in the page isn't, the page will still be reloaded if the CSS
|
||||
# file is contained in the message sent to LiveReload. Additionally, the
|
||||
# path matching is very loose so that a message to reload "/" will always
|
||||
# lead the page to reload since every page starts with "/".
|
||||
Jekyll::Hooks.register(:site, :post_write) do
|
||||
if @changed_pages && @reload_reactor && @reload_reactor.running?
|
||||
ignore, @changed_pages = @changed_pages.partition do |p|
|
||||
Array(opts["livereload_ignore"]).any? do |filter|
|
||||
File.fnmatch(filter, Jekyll.sanitized_path(p.relative_path))
|
||||
end
|
||||
end
|
||||
Jekyll.logger.debug "LiveReload:", "Ignoring #{ignore.map(&:relative_path)}"
|
||||
@reload_reactor.reload(@changed_pages)
|
||||
end
|
||||
@changed_pages = nil
|
||||
end
|
||||
end
|
||||
# rubocop:enable Metrics/AbcSize
|
||||
|
||||
# Do a base pre-setup of WEBRick so that everything is in place
|
||||
# when we get ready to party, checking for an setting up an error page
|
||||
# and making sure our destination exists.
|
||||
|
||||
def setup(destination)
|
||||
require_relative "serve/servlet"
|
||||
|
||||
FileUtils.mkdir_p(destination)
|
||||
if File.exist?(File.join(destination, "404.html"))
|
||||
WEBrick::HTTPResponse.class_eval do
|
||||
def create_error_page
|
||||
@header["Content-Type"] = "text/html; charset=UTF-8"
|
||||
@body = IO.read(File.join(@config[:DocumentRoot], "404.html"))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def webrick_opts(opts)
|
||||
opts = {
|
||||
:JekyllOptions => opts,
|
||||
:DoNotReverseLookup => true,
|
||||
:MimeTypes => mime_types,
|
||||
:DocumentRoot => opts["destination"],
|
||||
:StartCallback => start_callback(opts["detach"]),
|
||||
:StopCallback => stop_callback(opts["detach"]),
|
||||
:BindAddress => opts["host"],
|
||||
:Port => opts["port"],
|
||||
:DirectoryIndex => DIRECTORY_INDEX,
|
||||
}
|
||||
|
||||
opts[:DirectoryIndex] = [] if opts[:JekyllOptions]["show_dir_listing"]
|
||||
|
||||
enable_ssl(opts)
|
||||
enable_logging(opts)
|
||||
opts
|
||||
end
|
||||
|
||||
def start_up_webrick(opts, destination)
|
||||
@reload_reactor.start(opts) if opts["livereload"]
|
||||
|
||||
@server = WEBrick::HTTPServer.new(webrick_opts(opts)).tap { |o| o.unmount("") }
|
||||
@server.mount(opts["baseurl"].to_s, Servlet, destination, file_handler_opts)
|
||||
|
||||
Jekyll.logger.info "Server address:", server_address(@server, opts)
|
||||
launch_browser @server, opts if opts["open_url"]
|
||||
boot_or_detach @server, opts
|
||||
end
|
||||
|
||||
# Recreate NondisclosureName under utf-8 circumstance
|
||||
def file_handler_opts
|
||||
WEBrick::Config::FileHandler.merge(
|
||||
:FancyIndexing => true,
|
||||
:NondisclosureName => [
|
||||
".ht*", "~*",
|
||||
]
|
||||
)
|
||||
end
|
||||
|
||||
def server_address(server, options = {})
|
||||
format_url(
|
||||
server.config[:SSLEnable],
|
||||
server.config[:BindAddress],
|
||||
server.config[:Port],
|
||||
options["baseurl"]
|
||||
)
|
||||
end
|
||||
|
||||
def format_url(ssl_enabled, address, port, baseurl = nil)
|
||||
format("%<prefix>s://%<address>s:%<port>i%<baseurl>s",
|
||||
:prefix => ssl_enabled ? "https" : "http",
|
||||
:address => address,
|
||||
:port => port,
|
||||
:baseurl => baseurl ? "#{baseurl}/" : "")
|
||||
end
|
||||
|
||||
def default_url(opts)
|
||||
config = configuration_from_options(opts)
|
||||
auth = config.values_at("host", "port").join(":")
|
||||
return config["url"] if auth == "127.0.0.1:4000"
|
||||
|
||||
format_url(
|
||||
config["ssl_cert"] && config["ssl_key"],
|
||||
config["host"] == "127.0.0.1" ? "localhost" : config["host"],
|
||||
config["port"]
|
||||
)
|
||||
end
|
||||
|
||||
def launch_browser(server, opts)
|
||||
address = server_address(server, opts)
|
||||
return system "start", address if Utils::Platforms.windows?
|
||||
return system "xdg-open", address if Utils::Platforms.linux?
|
||||
return system "open", address if Utils::Platforms.osx?
|
||||
|
||||
Jekyll.logger.error "Refusing to launch browser; " \
|
||||
"Platform launcher unknown."
|
||||
end
|
||||
|
||||
# Keep in our area with a thread or detach the server as requested
|
||||
# by the user. This method determines what we do based on what you
|
||||
# ask us to do.
|
||||
def boot_or_detach(server, opts)
|
||||
if opts["detach"]
|
||||
pid = Process.fork do
|
||||
server.start
|
||||
end
|
||||
|
||||
Process.detach(pid)
|
||||
Jekyll.logger.info "Server detached with pid '#{pid}'.", \
|
||||
"Run `pkill -f jekyll' or `kill -9 #{pid}'" \
|
||||
" to stop the server."
|
||||
else
|
||||
t = Thread.new { server.start }
|
||||
trap("INT") { server.shutdown }
|
||||
t.join
|
||||
end
|
||||
end
|
||||
|
||||
# Make the stack verbose if the user requests it.
|
||||
def enable_logging(opts)
|
||||
opts[:AccessLog] = []
|
||||
level = WEBrick::Log.const_get(opts[:JekyllOptions]["verbose"] ? :DEBUG : :WARN)
|
||||
opts[:Logger] = WEBrick::Log.new($stdout, level)
|
||||
end
|
||||
|
||||
# Add SSL to the stack if the user triggers --enable-ssl and they
|
||||
# provide both types of certificates commonly needed. Raise if they
|
||||
# forget to add one of the certificates.
|
||||
def enable_ssl(opts)
|
||||
cert, key, src =
|
||||
opts[:JekyllOptions].values_at("ssl_cert", "ssl_key", "source")
|
||||
|
||||
return if cert.nil? && key.nil?
|
||||
raise "Missing --ssl_cert or --ssl_key. Both are required." unless cert && key
|
||||
|
||||
require "openssl"
|
||||
require "webrick/https"
|
||||
|
||||
opts[:SSLCertificate] = OpenSSL::X509::Certificate.new(read_file(src, cert))
|
||||
begin
|
||||
opts[:SSLPrivateKey] = OpenSSL::PKey::RSA.new(read_file(src, key))
|
||||
rescue StandardError
|
||||
if defined?(OpenSSL::PKey::EC)
|
||||
opts[:SSLPrivateKey] = OpenSSL::PKey::EC.new(read_file(src, key))
|
||||
else
|
||||
raise
|
||||
end
|
||||
end
|
||||
opts[:SSLEnable] = true
|
||||
end
|
||||
|
||||
def start_callback(detached)
|
||||
unless detached
|
||||
proc do
|
||||
mutex.synchronize do
|
||||
# Block until EventMachine reactor starts
|
||||
@reload_reactor&.started_event&.wait
|
||||
@running = true
|
||||
Jekyll.logger.info("Server running...", "press ctrl-c to stop.")
|
||||
@run_cond.broadcast
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def stop_callback(detached)
|
||||
unless detached
|
||||
proc do
|
||||
mutex.synchronize do
|
||||
unless @reload_reactor.nil?
|
||||
@reload_reactor.stop
|
||||
@reload_reactor.stopped_event.wait
|
||||
end
|
||||
@running = false
|
||||
@run_cond.broadcast
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def mime_types
|
||||
file = File.expand_path("../mime.types", __dir__)
|
||||
WEBrick::HTTPUtils.load_mime_types(file)
|
||||
end
|
||||
|
||||
def read_file(source_dir, file_path)
|
||||
File.read(Jekyll.sanitized_path(source_dir, file_path))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
122
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/commands/serve/live_reload_reactor.rb
vendored
Normal file
122
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/commands/serve/live_reload_reactor.rb
vendored
Normal file
@@ -0,0 +1,122 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "em-websocket"
|
||||
|
||||
require_relative "websockets"
|
||||
|
||||
module Jekyll
|
||||
module Commands
|
||||
class Serve
|
||||
class LiveReloadReactor
|
||||
attr_reader :started_event
|
||||
attr_reader :stopped_event
|
||||
attr_reader :thread
|
||||
|
||||
def initialize
|
||||
@websockets = []
|
||||
@connections_count = 0
|
||||
@started_event = Utils::ThreadEvent.new
|
||||
@stopped_event = Utils::ThreadEvent.new
|
||||
end
|
||||
|
||||
def stop
|
||||
# There is only one EventMachine instance per Ruby process so stopping
|
||||
# it here will stop the reactor thread we have running.
|
||||
EM.stop if EM.reactor_running?
|
||||
Jekyll.logger.debug "LiveReload Server:", "halted"
|
||||
end
|
||||
|
||||
def running?
|
||||
EM.reactor_running?
|
||||
end
|
||||
|
||||
def handle_websockets_event(websocket)
|
||||
websocket.onopen { |handshake| connect(websocket, handshake) }
|
||||
websocket.onclose { disconnect(websocket) }
|
||||
websocket.onmessage { |msg| print_message(msg) }
|
||||
websocket.onerror { |error| log_error(error) }
|
||||
end
|
||||
|
||||
def start(opts)
|
||||
@thread = Thread.new do
|
||||
# Use epoll if the kernel supports it
|
||||
EM.epoll
|
||||
EM.run do
|
||||
EM.error_handler { |e| log_error(e) }
|
||||
|
||||
EM.start_server(
|
||||
opts["host"],
|
||||
opts["livereload_port"],
|
||||
HttpAwareConnection,
|
||||
opts
|
||||
) do |ws|
|
||||
handle_websockets_event(ws)
|
||||
end
|
||||
|
||||
# Notify blocked threads that EventMachine has started or shutdown
|
||||
EM.schedule { @started_event.set }
|
||||
EM.add_shutdown_hook { @stopped_event.set }
|
||||
|
||||
Jekyll.logger.info "LiveReload address:",
|
||||
"http://#{opts["host"]}:#{opts["livereload_port"]}"
|
||||
end
|
||||
end
|
||||
@thread.abort_on_exception = true
|
||||
end
|
||||
|
||||
# For a description of the protocol see
|
||||
# http://feedback.livereload.com/knowledgebase/articles/86174-livereload-protocol
|
||||
def reload(pages)
|
||||
pages.each do |p|
|
||||
json_message = JSON.dump(
|
||||
:command => "reload",
|
||||
:path => p.url,
|
||||
:liveCSS => true
|
||||
)
|
||||
|
||||
Jekyll.logger.debug "LiveReload:", "Reloading #{p.url}"
|
||||
Jekyll.logger.debug "", json_message
|
||||
@websockets.each { |ws| ws.send(json_message) }
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def connect(websocket, handshake)
|
||||
@connections_count += 1
|
||||
if @connections_count == 1
|
||||
message = "Browser connected"
|
||||
message += " over SSL/TLS" if handshake.secure?
|
||||
Jekyll.logger.info "LiveReload:", message
|
||||
end
|
||||
websocket.send(
|
||||
JSON.dump(
|
||||
:command => "hello",
|
||||
:protocols => ["http://livereload.com/protocols/official-7"],
|
||||
:serverName => "jekyll"
|
||||
)
|
||||
)
|
||||
|
||||
@websockets << websocket
|
||||
end
|
||||
|
||||
def disconnect(websocket)
|
||||
@websockets.delete(websocket)
|
||||
end
|
||||
|
||||
def print_message(json_message)
|
||||
msg = JSON.parse(json_message)
|
||||
# Not sure what the 'url' command even does in LiveReload. The spec is silent
|
||||
# on its purpose.
|
||||
Jekyll.logger.info "LiveReload:", "Browser URL: #{msg["url"]}" if msg["command"] == "url"
|
||||
end
|
||||
|
||||
def log_error(error)
|
||||
Jekyll.logger.error "LiveReload experienced an error. " \
|
||||
"Run with --trace for more information."
|
||||
raise error
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
1183
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/commands/serve/livereload_assets/livereload.js
vendored
Normal file
1183
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/commands/serve/livereload_assets/livereload.js
vendored
Normal file
File diff suppressed because it is too large
Load Diff
202
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/commands/serve/servlet.rb
vendored
Normal file
202
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/commands/serve/servlet.rb
vendored
Normal file
@@ -0,0 +1,202 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "webrick"
|
||||
|
||||
module Jekyll
|
||||
module Commands
|
||||
class Serve
|
||||
# This class is used to determine if the Servlet should modify a served file
|
||||
# to insert the LiveReload script tags
|
||||
class SkipAnalyzer
|
||||
BAD_USER_AGENTS = [%r!MSIE!].freeze
|
||||
|
||||
def self.skip_processing?(request, response, options)
|
||||
new(request, response, options).skip_processing?
|
||||
end
|
||||
|
||||
def initialize(request, response, options)
|
||||
@options = options
|
||||
@request = request
|
||||
@response = response
|
||||
end
|
||||
|
||||
def skip_processing?
|
||||
!html? || chunked? || inline? || bad_browser?
|
||||
end
|
||||
|
||||
def chunked?
|
||||
@response["Transfer-Encoding"] == "chunked"
|
||||
end
|
||||
|
||||
def inline?
|
||||
@response["Content-Disposition"].to_s.start_with?("inline")
|
||||
end
|
||||
|
||||
def bad_browser?
|
||||
BAD_USER_AGENTS.any? { |pattern| pattern.match?(@request["User-Agent"]) }
|
||||
end
|
||||
|
||||
def html?
|
||||
@response["Content-Type"].to_s.include?("text/html")
|
||||
end
|
||||
end
|
||||
|
||||
# This class inserts the LiveReload script tags into HTML as it is served
|
||||
class BodyProcessor
|
||||
HEAD_TAG_REGEX = %r!<head>|<head[^(er)][^<]*>!.freeze
|
||||
|
||||
attr_reader :content_length, :new_body, :livereload_added
|
||||
|
||||
def initialize(body, options)
|
||||
@body = body
|
||||
@options = options
|
||||
@processed = false
|
||||
end
|
||||
|
||||
def processed?
|
||||
@processed
|
||||
end
|
||||
|
||||
# rubocop:disable Metrics/MethodLength
|
||||
def process!
|
||||
@new_body = []
|
||||
# @body will usually be a File object but Strings occur in rare cases
|
||||
if @body.respond_to?(:each)
|
||||
begin
|
||||
@body.each { |line| @new_body << line.to_s }
|
||||
ensure
|
||||
@body.close
|
||||
end
|
||||
else
|
||||
@new_body = @body.lines
|
||||
end
|
||||
|
||||
@content_length = 0
|
||||
@livereload_added = false
|
||||
|
||||
@new_body.each do |line|
|
||||
if !@livereload_added && line["<head"]
|
||||
line.gsub!(HEAD_TAG_REGEX) do |match|
|
||||
%(#{match}#{template.result(binding)})
|
||||
end
|
||||
|
||||
@livereload_added = true
|
||||
end
|
||||
|
||||
@content_length += line.bytesize
|
||||
@processed = true
|
||||
end
|
||||
@new_body = @new_body.join
|
||||
end
|
||||
# rubocop:enable Metrics/MethodLength
|
||||
|
||||
def template
|
||||
# Unclear what "snipver" does. Doc at
|
||||
# https://github.com/livereload/livereload-js states that the recommended
|
||||
# setting is 1.
|
||||
|
||||
# Complicated JavaScript to ensure that livereload.js is loaded from the
|
||||
# same origin as the page. Mostly useful for dealing with the browser's
|
||||
# distinction between 'localhost' and 127.0.0.1
|
||||
@template ||= ERB.new(<<~TEMPLATE)
|
||||
<script>
|
||||
document.write(
|
||||
'<script src="http://' +
|
||||
(location.host || 'localhost').split(':')[0] +
|
||||
':<%=@options["livereload_port"] %>/livereload.js?snipver=1<%= livereload_args %>"' +
|
||||
'></' +
|
||||
'script>');
|
||||
</script>
|
||||
TEMPLATE
|
||||
end
|
||||
|
||||
def livereload_args
|
||||
# XHTML standard requires ampersands to be encoded as entities when in
|
||||
# attributes. See http://stackoverflow.com/a/2190292
|
||||
src = ""
|
||||
if @options["livereload_min_delay"]
|
||||
src += "&mindelay=#{@options["livereload_min_delay"]}"
|
||||
end
|
||||
if @options["livereload_max_delay"]
|
||||
src += "&maxdelay=#{@options["livereload_max_delay"]}"
|
||||
end
|
||||
src += "&port=#{@options["livereload_port"]}" if @options["livereload_port"]
|
||||
src
|
||||
end
|
||||
end
|
||||
|
||||
class Servlet < WEBrick::HTTPServlet::FileHandler
|
||||
DEFAULTS = {
|
||||
"Cache-Control" => "private, max-age=0, proxy-revalidate, " \
|
||||
"no-store, no-cache, must-revalidate",
|
||||
}.freeze
|
||||
|
||||
def initialize(server, root, callbacks)
|
||||
# So we can access them easily.
|
||||
@jekyll_opts = server.config[:JekyllOptions]
|
||||
set_defaults
|
||||
super
|
||||
end
|
||||
|
||||
def search_index_file(req, res)
|
||||
super ||
|
||||
search_file(req, res, ".html") ||
|
||||
search_file(req, res, ".xhtml")
|
||||
end
|
||||
|
||||
# Add the ability to tap file.html the same way that Nginx does on our
|
||||
# Docker images (or on GitHub Pages.) The difference is that we might end
|
||||
# up with a different preference on which comes first.
|
||||
|
||||
def search_file(req, res, basename)
|
||||
# /file.* > /file/index.html > /file.html
|
||||
super ||
|
||||
super(req, res, "#{basename}.html") ||
|
||||
super(req, res, "#{basename}.xhtml")
|
||||
end
|
||||
|
||||
# rubocop:disable Naming/MethodName
|
||||
def do_GET(req, res)
|
||||
rtn = super
|
||||
|
||||
if @jekyll_opts["livereload"]
|
||||
return rtn if SkipAnalyzer.skip_processing?(req, res, @jekyll_opts)
|
||||
|
||||
processor = BodyProcessor.new(res.body, @jekyll_opts)
|
||||
processor.process!
|
||||
res.body = processor.new_body
|
||||
res.content_length = processor.content_length.to_s
|
||||
|
||||
if processor.livereload_added
|
||||
# Add a header to indicate that the page content has been modified
|
||||
res["X-Rack-LiveReload"] = "1"
|
||||
end
|
||||
end
|
||||
|
||||
validate_and_ensure_charset(req, res)
|
||||
res.header.merge!(@headers)
|
||||
rtn
|
||||
end
|
||||
# rubocop:enable Naming/MethodName
|
||||
|
||||
private
|
||||
|
||||
def validate_and_ensure_charset(_req, res)
|
||||
key = res.header.keys.grep(%r!content-type!i).first
|
||||
typ = res.header[key]
|
||||
|
||||
unless %r!;\s*charset=!.match?(typ)
|
||||
res.header[key] = "#{typ}; charset=#{@jekyll_opts["encoding"]}"
|
||||
end
|
||||
end
|
||||
|
||||
def set_defaults
|
||||
hash_ = @jekyll_opts.fetch("webrick", {}).fetch("headers", {})
|
||||
DEFAULTS.each_with_object(@headers = hash_) do |(key, val), hash|
|
||||
hash[key] = val unless hash.key?(key)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
81
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/commands/serve/websockets.rb
vendored
Normal file
81
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/commands/serve/websockets.rb
vendored
Normal file
@@ -0,0 +1,81 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "http/parser"
|
||||
|
||||
module Jekyll
|
||||
module Commands
|
||||
class Serve
|
||||
# The LiveReload protocol requires the server to serve livereload.js over HTTP
|
||||
# despite the fact that the protocol itself uses WebSockets. This custom connection
|
||||
# class addresses the dual protocols that the server needs to understand.
|
||||
class HttpAwareConnection < EventMachine::WebSocket::Connection
|
||||
attr_reader :reload_body, :reload_size
|
||||
|
||||
def initialize(_opts)
|
||||
# If EventMachine SSL support on Windows ever gets better, the code below will
|
||||
# set up the reactor to handle SSL
|
||||
#
|
||||
# @ssl_enabled = opts["ssl_cert"] && opts["ssl_key"]
|
||||
# if @ssl_enabled
|
||||
# em_opts[:tls_options] = {
|
||||
# :private_key_file => Jekyll.sanitized_path(opts["source"], opts["ssl_key"]),
|
||||
# :cert_chain_file => Jekyll.sanitized_path(opts["source"], opts["ssl_cert"])
|
||||
# }
|
||||
# em_opts[:secure] = true
|
||||
# end
|
||||
|
||||
# This is too noisy even for --verbose, but uncomment if you need it for
|
||||
# a specific WebSockets issue. Adding ?LR-verbose=true onto the URL will
|
||||
# enable logging on the client side.
|
||||
# em_opts[:debug] = true
|
||||
|
||||
em_opts = {}
|
||||
super(em_opts)
|
||||
|
||||
reload_file = File.join(Serve.singleton_class::LIVERELOAD_DIR, "livereload.js")
|
||||
|
||||
@reload_body = File.read(reload_file)
|
||||
@reload_size = @reload_body.bytesize
|
||||
end
|
||||
|
||||
# rubocop:disable Metrics/MethodLength
|
||||
def dispatch(data)
|
||||
parser = Http::Parser.new
|
||||
parser << data
|
||||
|
||||
# WebSockets requests will have a Connection: Upgrade header
|
||||
if parser.http_method != "GET" || parser.upgrade?
|
||||
super
|
||||
elsif parser.request_url.start_with?("/livereload.js")
|
||||
headers = [
|
||||
"HTTP/1.1 200 OK",
|
||||
"Content-Type: application/javascript",
|
||||
"Content-Length: #{reload_size}",
|
||||
"",
|
||||
"",
|
||||
].join("\r\n")
|
||||
send_data(headers)
|
||||
|
||||
# stream_file_data would free us from keeping livereload.js in memory
|
||||
# but JRuby blocks on that call and never returns
|
||||
send_data(reload_body)
|
||||
close_connection_after_writing
|
||||
else
|
||||
body = "This port only serves livereload.js over HTTP.\n"
|
||||
headers = [
|
||||
"HTTP/1.1 400 Bad Request",
|
||||
"Content-Type: text/plain",
|
||||
"Content-Length: #{body.bytesize}",
|
||||
"",
|
||||
"",
|
||||
].join("\r\n")
|
||||
send_data(headers)
|
||||
send_data(body)
|
||||
close_connection_after_writing
|
||||
end
|
||||
end
|
||||
# rubocop:enable Metrics/MethodLength
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
313
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/configuration.rb
vendored
Normal file
313
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/configuration.rb
vendored
Normal file
@@ -0,0 +1,313 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Jekyll
|
||||
class Configuration < Hash
|
||||
# Default options. Overridden by values in _config.yml.
|
||||
# Strings rather than symbols are used for compatibility with YAML.
|
||||
DEFAULTS = {
|
||||
# Where things are
|
||||
"source" => Dir.pwd,
|
||||
"destination" => File.join(Dir.pwd, "_site"),
|
||||
"collections_dir" => "",
|
||||
"cache_dir" => ".jekyll-cache",
|
||||
"plugins_dir" => "_plugins",
|
||||
"layouts_dir" => "_layouts",
|
||||
"data_dir" => "_data",
|
||||
"includes_dir" => "_includes",
|
||||
"collections" => {},
|
||||
|
||||
# Handling Reading
|
||||
"safe" => false,
|
||||
"include" => [".htaccess"],
|
||||
"exclude" => [],
|
||||
"keep_files" => [".git", ".svn"],
|
||||
"encoding" => "utf-8",
|
||||
"markdown_ext" => "markdown,mkdown,mkdn,mkd,md",
|
||||
"strict_front_matter" => false,
|
||||
|
||||
# Filtering Content
|
||||
"show_drafts" => nil,
|
||||
"limit_posts" => 0,
|
||||
"future" => false,
|
||||
"unpublished" => false,
|
||||
|
||||
# Plugins
|
||||
"whitelist" => [],
|
||||
"plugins" => [],
|
||||
|
||||
# Conversion
|
||||
"markdown" => "kramdown",
|
||||
"highlighter" => "rouge",
|
||||
"lsi" => false,
|
||||
"excerpt_separator" => "\n\n",
|
||||
"incremental" => false,
|
||||
|
||||
# Serving
|
||||
"detach" => false, # default to not detaching the server
|
||||
"port" => "4000",
|
||||
"host" => "127.0.0.1",
|
||||
"baseurl" => nil, # this mounts at /, i.e. no subdirectory
|
||||
"show_dir_listing" => false,
|
||||
|
||||
# Output Configuration
|
||||
"permalink" => "date",
|
||||
"paginate_path" => "/page:num",
|
||||
"timezone" => nil, # use the local timezone
|
||||
|
||||
"quiet" => false,
|
||||
"verbose" => false,
|
||||
"defaults" => [],
|
||||
|
||||
"liquid" => {
|
||||
"error_mode" => "warn",
|
||||
"strict_filters" => false,
|
||||
"strict_variables" => false,
|
||||
},
|
||||
|
||||
"kramdown" => {
|
||||
"auto_ids" => true,
|
||||
"toc_levels" => (1..6).to_a,
|
||||
"entity_output" => "as_char",
|
||||
"smart_quotes" => "lsquo,rsquo,ldquo,rdquo",
|
||||
"input" => "GFM",
|
||||
"hard_wrap" => false,
|
||||
"guess_lang" => true,
|
||||
"footnote_nr" => 1,
|
||||
"show_warnings" => false,
|
||||
},
|
||||
}.each_with_object(Configuration.new) { |(k, v), hsh| hsh[k] = v.freeze }.freeze
|
||||
|
||||
class << self
|
||||
# Static: Produce a Configuration ready for use in a Site.
|
||||
# It takes the input, fills in the defaults where values do not exist.
|
||||
#
|
||||
# user_config - a Hash or Configuration of overrides.
|
||||
#
|
||||
# Returns a Configuration filled with defaults.
|
||||
def from(user_config)
|
||||
Utils.deep_merge_hashes(DEFAULTS, Configuration[user_config].stringify_keys)
|
||||
.add_default_collections.add_default_excludes
|
||||
end
|
||||
end
|
||||
|
||||
# Public: Turn all keys into string
|
||||
#
|
||||
# Return a copy of the hash where all its keys are strings
|
||||
def stringify_keys
|
||||
each_with_object({}) { |(k, v), hsh| hsh[k.to_s] = v }
|
||||
end
|
||||
|
||||
def get_config_value_with_override(config_key, override)
|
||||
override[config_key] || self[config_key] || DEFAULTS[config_key]
|
||||
end
|
||||
|
||||
# Public: Directory of the Jekyll source folder
|
||||
#
|
||||
# override - the command-line options hash
|
||||
#
|
||||
# Returns the path to the Jekyll source directory
|
||||
def source(override)
|
||||
get_config_value_with_override("source", override)
|
||||
end
|
||||
|
||||
def quiet(override = {})
|
||||
get_config_value_with_override("quiet", override)
|
||||
end
|
||||
alias_method :quiet?, :quiet
|
||||
|
||||
def verbose(override = {})
|
||||
get_config_value_with_override("verbose", override)
|
||||
end
|
||||
alias_method :verbose?, :verbose
|
||||
|
||||
def safe_load_file(filename)
|
||||
case File.extname(filename)
|
||||
when %r!\.toml!i
|
||||
Jekyll::External.require_with_graceful_fail("tomlrb") unless defined?(Tomlrb)
|
||||
Tomlrb.load_file(filename)
|
||||
when %r!\.ya?ml!i
|
||||
SafeYAML.load_file(filename) || {}
|
||||
else
|
||||
raise ArgumentError,
|
||||
"No parser for '#{filename}' is available. Use a .y(a)ml or .toml file instead."
|
||||
end
|
||||
end
|
||||
|
||||
# Public: Generate list of configuration files from the override
|
||||
#
|
||||
# override - the command-line options hash
|
||||
#
|
||||
# Returns an Array of config files
|
||||
def config_files(override)
|
||||
# Adjust verbosity quickly
|
||||
Jekyll.logger.adjust_verbosity(
|
||||
:quiet => quiet?(override),
|
||||
:verbose => verbose?(override)
|
||||
)
|
||||
|
||||
# Get configuration from <source>/_config.yml or <source>/<config_file>
|
||||
config_files = override["config"]
|
||||
if config_files.to_s.empty?
|
||||
default = %w(yml yaml toml).find(-> { "yml" }) do |ext|
|
||||
File.exist?(Jekyll.sanitized_path(source(override), "_config.#{ext}"))
|
||||
end
|
||||
config_files = Jekyll.sanitized_path(source(override), "_config.#{default}")
|
||||
@default_config_file = true
|
||||
end
|
||||
Array(config_files)
|
||||
end
|
||||
|
||||
# Public: Read configuration and return merged Hash
|
||||
#
|
||||
# file - the path to the YAML file to be read in
|
||||
#
|
||||
# Returns this configuration, overridden by the values in the file
|
||||
def read_config_file(file)
|
||||
file = File.expand_path(file)
|
||||
next_config = safe_load_file(file)
|
||||
|
||||
unless next_config.is_a?(Hash)
|
||||
raise ArgumentError, "Configuration file: (INVALID) #{file}".yellow
|
||||
end
|
||||
|
||||
Jekyll.logger.info "Configuration file:", file
|
||||
next_config
|
||||
rescue SystemCallError
|
||||
if @default_config_file ||= nil
|
||||
Jekyll.logger.warn "Configuration file:", "none"
|
||||
{}
|
||||
else
|
||||
Jekyll.logger.error "Fatal:", "The configuration file '#{file}' could not be found."
|
||||
raise LoadError, "The Configuration file '#{file}' could not be found."
|
||||
end
|
||||
end
|
||||
|
||||
# Public: Read in a list of configuration files and merge with this hash
|
||||
#
|
||||
# files - the list of configuration file paths
|
||||
#
|
||||
# Returns the full configuration, with the defaults overridden by the values in the
|
||||
# configuration files
|
||||
def read_config_files(files)
|
||||
configuration = clone
|
||||
|
||||
begin
|
||||
files.each do |config_file|
|
||||
next if config_file.nil? || config_file.empty?
|
||||
|
||||
new_config = read_config_file(config_file)
|
||||
configuration = Utils.deep_merge_hashes(configuration, new_config)
|
||||
end
|
||||
rescue ArgumentError => e
|
||||
Jekyll.logger.warn "WARNING:", "Error reading configuration. Using defaults (and options)."
|
||||
warn e
|
||||
end
|
||||
|
||||
configuration.validate.add_default_collections
|
||||
end
|
||||
|
||||
# Public: Split a CSV string into an array containing its values
|
||||
#
|
||||
# csv - the string of comma-separated values
|
||||
#
|
||||
# Returns an array of the values contained in the CSV
|
||||
def csv_to_array(csv)
|
||||
csv.split(",").map(&:strip)
|
||||
end
|
||||
|
||||
# Public: Ensure the proper options are set in the configuration
|
||||
#
|
||||
# Returns the configuration Hash
|
||||
def validate
|
||||
config = clone
|
||||
|
||||
check_plugins(config)
|
||||
check_include_exclude(config)
|
||||
|
||||
config
|
||||
end
|
||||
|
||||
def add_default_collections
|
||||
config = clone
|
||||
|
||||
# It defaults to `{}`, so this is only if someone sets it to null manually.
|
||||
return config if config["collections"].nil?
|
||||
|
||||
# Ensure we have a hash.
|
||||
if config["collections"].is_a?(Array)
|
||||
config["collections"] = config["collections"].each_with_object({}) do |collection, hash|
|
||||
hash[collection] = {}
|
||||
end
|
||||
end
|
||||
|
||||
config["collections"] = Utils.deep_merge_hashes(
|
||||
{ "posts" => {} }, config["collections"]
|
||||
).tap do |collections|
|
||||
collections["posts"]["output"] = true
|
||||
if config["permalink"]
|
||||
collections["posts"]["permalink"] ||= style_to_permalink(config["permalink"])
|
||||
end
|
||||
end
|
||||
|
||||
config
|
||||
end
|
||||
|
||||
DEFAULT_EXCLUDES = %w(
|
||||
.sass-cache .jekyll-cache
|
||||
gemfiles Gemfile Gemfile.lock
|
||||
node_modules
|
||||
vendor/bundle/ vendor/cache/ vendor/gems/ vendor/ruby/
|
||||
).freeze
|
||||
|
||||
def add_default_excludes
|
||||
config = clone
|
||||
return config if config["exclude"].nil?
|
||||
|
||||
config["exclude"].concat(DEFAULT_EXCLUDES).uniq!
|
||||
config
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
STYLE_TO_PERMALINK = {
|
||||
:none => "/:categories/:title:output_ext",
|
||||
:date => "/:categories/:year/:month/:day/:title:output_ext",
|
||||
:ordinal => "/:categories/:year/:y_day/:title:output_ext",
|
||||
:pretty => "/:categories/:year/:month/:day/:title/",
|
||||
:weekdate => "/:categories/:year/W:week/:short_day/:title:output_ext",
|
||||
}.freeze
|
||||
|
||||
private_constant :STYLE_TO_PERMALINK
|
||||
|
||||
def style_to_permalink(permalink_style)
|
||||
STYLE_TO_PERMALINK[permalink_style.to_sym] || permalink_style.to_s
|
||||
end
|
||||
|
||||
def check_include_exclude(config)
|
||||
%w(include exclude).each do |option|
|
||||
next unless config.key?(option)
|
||||
next if config[option].is_a?(Array)
|
||||
|
||||
raise Jekyll::Errors::InvalidConfigurationError,
|
||||
"'#{option}' should be set as an array, but was: #{config[option].inspect}."
|
||||
end
|
||||
end
|
||||
|
||||
# Private: Checks if the `plugins` config is a String
|
||||
#
|
||||
# config - the config hash
|
||||
#
|
||||
# Raises a Jekyll::Errors::InvalidConfigurationError if the config `plugins`
|
||||
# is not an Array.
|
||||
def check_plugins(config)
|
||||
return unless config.key?("plugins")
|
||||
return if config["plugins"].is_a?(Array)
|
||||
|
||||
Jekyll.logger.error "'plugins' should be set as an array of gem-names, but was: " \
|
||||
"#{config["plugins"].inspect}. Use 'plugins_dir' instead to set the directory " \
|
||||
"for your non-gemified Ruby plugins."
|
||||
raise Jekyll::Errors::InvalidConfigurationError,
|
||||
"'plugins' should be set as an array, but was: #{config["plugins"].inspect}."
|
||||
end
|
||||
end
|
||||
end
|
||||
54
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/converter.rb
vendored
Normal file
54
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/converter.rb
vendored
Normal file
@@ -0,0 +1,54 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Jekyll
|
||||
class Converter < Plugin
|
||||
# Public: Get or set the highlighter prefix. When an argument is specified,
|
||||
# the prefix will be set. If no argument is specified, the current prefix
|
||||
# will be returned.
|
||||
#
|
||||
# highlighter_prefix - The String prefix (default: nil).
|
||||
#
|
||||
# Returns the String prefix.
|
||||
def self.highlighter_prefix(highlighter_prefix = nil)
|
||||
unless defined?(@highlighter_prefix) && highlighter_prefix.nil?
|
||||
@highlighter_prefix = highlighter_prefix
|
||||
end
|
||||
@highlighter_prefix
|
||||
end
|
||||
|
||||
# Public: Get or set the highlighter suffix. When an argument is specified,
|
||||
# the suffix will be set. If no argument is specified, the current suffix
|
||||
# will be returned.
|
||||
#
|
||||
# highlighter_suffix - The String suffix (default: nil).
|
||||
#
|
||||
# Returns the String suffix.
|
||||
def self.highlighter_suffix(highlighter_suffix = nil)
|
||||
unless defined?(@highlighter_suffix) && highlighter_suffix.nil?
|
||||
@highlighter_suffix = highlighter_suffix
|
||||
end
|
||||
@highlighter_suffix
|
||||
end
|
||||
|
||||
# Initialize the converter.
|
||||
#
|
||||
# Returns an initialized Converter.
|
||||
def initialize(config = {})
|
||||
@config = config
|
||||
end
|
||||
|
||||
# Get the highlighter prefix.
|
||||
#
|
||||
# Returns the String prefix.
|
||||
def highlighter_prefix
|
||||
self.class.highlighter_prefix
|
||||
end
|
||||
|
||||
# Get the highlighter suffix.
|
||||
#
|
||||
# Returns the String suffix.
|
||||
def highlighter_suffix
|
||||
self.class.highlighter_suffix
|
||||
end
|
||||
end
|
||||
end
|
||||
41
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/converters/identity.rb
vendored
Normal file
41
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/converters/identity.rb
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Jekyll
|
||||
module Converters
|
||||
# Identity converter. Returns same content as given.
|
||||
# For more info on converters see https://jekyllrb.com/docs/plugins/converters/
|
||||
class Identity < Converter
|
||||
safe true
|
||||
|
||||
priority :lowest
|
||||
|
||||
# Public: Does the given extension match this converter's list of acceptable extensions?
|
||||
# Takes one argument: the file's extension (including the dot).
|
||||
#
|
||||
# _ext - The String extension to check (not relevant here)
|
||||
#
|
||||
# Returns true since it always matches.
|
||||
def matches(_ext)
|
||||
true
|
||||
end
|
||||
|
||||
# Public: The extension to be given to the output file (including the dot).
|
||||
#
|
||||
# ext - The String extension or original file.
|
||||
#
|
||||
# Returns The String output file extension.
|
||||
def output_ext(ext)
|
||||
ext
|
||||
end
|
||||
|
||||
# Logic to do the content conversion.
|
||||
#
|
||||
# content - String content of file (without front matter).
|
||||
#
|
||||
# Returns a String of the converted content.
|
||||
def convert(content)
|
||||
content
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
113
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/converters/markdown.rb
vendored
Normal file
113
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/converters/markdown.rb
vendored
Normal file
@@ -0,0 +1,113 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Jekyll
|
||||
module Converters
|
||||
# Markdown converter.
|
||||
# For more info on converters see https://jekyllrb.com/docs/plugins/converters/
|
||||
class Markdown < Converter
|
||||
highlighter_prefix "\n"
|
||||
highlighter_suffix "\n"
|
||||
safe true
|
||||
|
||||
def setup
|
||||
return if @setup ||= false
|
||||
|
||||
unless (@parser = get_processor)
|
||||
if @config["safe"]
|
||||
Jekyll.logger.warn "Build Warning:", "Custom processors are not loaded in safe mode"
|
||||
end
|
||||
|
||||
Jekyll.logger.error "Markdown processor:",
|
||||
"#{@config["markdown"].inspect} is not a valid Markdown processor."
|
||||
Jekyll.logger.error "", "Available processors are: #{valid_processors.join(", ")}"
|
||||
Jekyll.logger.error ""
|
||||
raise Errors::FatalException, "Invalid Markdown processor given: #{@config["markdown"]}"
|
||||
end
|
||||
|
||||
@cache = Jekyll::Cache.new("Jekyll::Converters::Markdown")
|
||||
@setup = true
|
||||
end
|
||||
|
||||
# RuboCop does not allow reader methods to have names starting with `get_`
|
||||
# To ensure compatibility, this check has been disabled on this method
|
||||
#
|
||||
# rubocop:disable Naming/AccessorMethodName
|
||||
def get_processor
|
||||
case @config["markdown"].downcase
|
||||
when "kramdown" then KramdownParser.new(@config)
|
||||
else
|
||||
custom_processor
|
||||
end
|
||||
end
|
||||
# rubocop:enable Naming/AccessorMethodName
|
||||
|
||||
# Public: Provides you with a list of processors comprised of the ones we support internally
|
||||
# and the ones that you have provided to us (if they're whitelisted for use in safe mode).
|
||||
#
|
||||
# Returns an array of symbols.
|
||||
def valid_processors
|
||||
[:kramdown] + third_party_processors
|
||||
end
|
||||
|
||||
# Public: A list of processors that you provide via plugins.
|
||||
#
|
||||
# Returns an array of symbols
|
||||
def third_party_processors
|
||||
self.class.constants - [:KramdownParser, :PRIORITIES]
|
||||
end
|
||||
|
||||
# Does the given extension match this converter's list of acceptable extensions?
|
||||
# Takes one argument: the file's extension (including the dot).
|
||||
#
|
||||
# ext - The String extension to check.
|
||||
#
|
||||
# Returns true if it matches, false otherwise.
|
||||
def matches(ext)
|
||||
extname_list.include?(ext.downcase)
|
||||
end
|
||||
|
||||
# Public: The extension to be given to the output file (including the dot).
|
||||
#
|
||||
# ext - The String extension or original file.
|
||||
#
|
||||
# Returns The String output file extension.
|
||||
def output_ext(_ext)
|
||||
".html"
|
||||
end
|
||||
|
||||
# Logic to do the content conversion.
|
||||
#
|
||||
# content - String content of file (without front matter).
|
||||
#
|
||||
# Returns a String of the converted content.
|
||||
def convert(content)
|
||||
setup
|
||||
@cache.getset(content) do
|
||||
@parser.convert(content)
|
||||
end
|
||||
end
|
||||
|
||||
def extname_list
|
||||
@extname_list ||= @config["markdown_ext"].split(",").map! { |e| ".#{e.downcase}" }
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def custom_processor
|
||||
converter_name = @config["markdown"]
|
||||
self.class.const_get(converter_name).new(@config) if custom_class_allowed?(converter_name)
|
||||
end
|
||||
|
||||
# Private: Determine whether a class name is an allowed custom
|
||||
# markdown class name.
|
||||
#
|
||||
# parser_name - the name of the parser class
|
||||
#
|
||||
# Returns true if the parser name contains only alphanumeric characters and is defined
|
||||
# within Jekyll::Converters::Markdown
|
||||
def custom_class_allowed?(parser_name)
|
||||
parser_name !~ %r![^A-Za-z0-9_]! && self.class.constants.include?(parser_name.to_sym)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
199
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/converters/markdown/kramdown_parser.rb
vendored
Normal file
199
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/converters/markdown/kramdown_parser.rb
vendored
Normal file
@@ -0,0 +1,199 @@
|
||||
# Frozen-string-literal: true
|
||||
|
||||
module Kramdown
|
||||
# A Kramdown::Document subclass meant to optimize memory usage from initializing
|
||||
# a kramdown document for parsing.
|
||||
#
|
||||
# The optimization is by using the same options Hash (and its derivatives) for
|
||||
# converting all Markdown documents in a Jekyll site.
|
||||
class JekyllDocument < Document
|
||||
class << self
|
||||
attr_reader :options, :parser
|
||||
|
||||
# The implementation is basically the core logic in +Kramdown::Document#initialize+
|
||||
#
|
||||
# rubocop:disable Naming/MemoizedInstanceVariableName
|
||||
def setup(options)
|
||||
@cache ||= {}
|
||||
|
||||
# reset variables on a subsequent set up with a different options Hash
|
||||
unless @cache[:id] == options.hash
|
||||
@options = @parser = nil
|
||||
@cache[:id] = options.hash
|
||||
end
|
||||
|
||||
@options ||= Options.merge(options).freeze
|
||||
@parser ||= begin
|
||||
parser_name = (@options[:input] || "kramdown").to_s
|
||||
parser_name = parser_name[0..0].upcase + parser_name[1..-1]
|
||||
try_require("parser", parser_name)
|
||||
|
||||
if Parser.const_defined?(parser_name)
|
||||
Parser.const_get(parser_name)
|
||||
else
|
||||
raise Kramdown::Error, "kramdown has no parser to handle the specified " \
|
||||
"input format: #{@options[:input]}"
|
||||
end
|
||||
end
|
||||
end
|
||||
# rubocop:enable Naming/MemoizedInstanceVariableName
|
||||
|
||||
private
|
||||
|
||||
def try_require(type, name)
|
||||
require "kramdown/#{type}/#{Utils.snake_case(name)}"
|
||||
rescue LoadError
|
||||
false
|
||||
end
|
||||
end
|
||||
|
||||
def initialize(source, options = {})
|
||||
JekyllDocument.setup(options)
|
||||
|
||||
@options = JekyllDocument.options
|
||||
@root, @warnings = JekyllDocument.parser.parse(source, @options)
|
||||
end
|
||||
|
||||
# Use Kramdown::Converter::Html class to convert this document into HTML.
|
||||
#
|
||||
# The implementation is basically an optimized version of core logic in
|
||||
# +Kramdown::Document#method_missing+ from kramdown-2.1.0.
|
||||
def to_html
|
||||
output, warnings = Kramdown::Converter::Html.convert(@root, @options)
|
||||
@warnings.concat(warnings)
|
||||
output
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
|
||||
module Jekyll
|
||||
module Converters
|
||||
class Markdown
|
||||
class KramdownParser
|
||||
CODERAY_DEFAULTS = {
|
||||
"css" => "style",
|
||||
"bold_every" => 10,
|
||||
"line_numbers" => "inline",
|
||||
"line_number_start" => 1,
|
||||
"tab_width" => 4,
|
||||
"wrap" => "div",
|
||||
}.freeze
|
||||
|
||||
def initialize(config)
|
||||
@main_fallback_highlighter = config["highlighter"] || "rouge"
|
||||
@config = config["kramdown"] || {}
|
||||
@highlighter = nil
|
||||
setup
|
||||
load_dependencies
|
||||
end
|
||||
|
||||
# Setup and normalize the configuration:
|
||||
# * Create Kramdown if it doesn't exist.
|
||||
# * Set syntax_highlighter, detecting enable_coderay and merging
|
||||
# highlighter if none.
|
||||
# * Merge kramdown[coderay] into syntax_highlighter_opts stripping coderay_.
|
||||
# * Make sure `syntax_highlighter_opts` exists.
|
||||
|
||||
def setup
|
||||
@config["syntax_highlighter"] ||= highlighter
|
||||
@config["syntax_highlighter_opts"] ||= {}
|
||||
@config["syntax_highlighter_opts"]["default_lang"] ||= "plaintext"
|
||||
@config["syntax_highlighter_opts"]["guess_lang"] = @config["guess_lang"]
|
||||
@config["coderay"] ||= {} # XXX: Legacy.
|
||||
modernize_coderay_config
|
||||
end
|
||||
|
||||
def convert(content)
|
||||
document = Kramdown::JekyllDocument.new(content, @config)
|
||||
html_output = document.to_html
|
||||
if @config["show_warnings"]
|
||||
document.warnings.each do |warning|
|
||||
Jekyll.logger.warn "Kramdown warning:", warning
|
||||
end
|
||||
end
|
||||
html_output
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def load_dependencies
|
||||
require "kramdown-parser-gfm" if @config["input"] == "GFM"
|
||||
|
||||
if highlighter == "coderay"
|
||||
Jekyll::External.require_with_graceful_fail("kramdown-syntax-coderay")
|
||||
end
|
||||
|
||||
# `mathjax` emgine is bundled within kramdown-2.x and will be handled by
|
||||
# kramdown itself.
|
||||
if (math_engine = @config["math_engine"]) && math_engine != "mathjax"
|
||||
Jekyll::External.require_with_graceful_fail("kramdown-math-#{math_engine}")
|
||||
end
|
||||
end
|
||||
|
||||
# config[kramdown][syntax_higlighter] >
|
||||
# config[kramdown][enable_coderay] >
|
||||
# config[highlighter]
|
||||
# Where `enable_coderay` is now deprecated because Kramdown
|
||||
# supports Rouge now too.
|
||||
def highlighter
|
||||
return @highlighter if @highlighter
|
||||
|
||||
if @config["syntax_highlighter"]
|
||||
return @highlighter = @config[
|
||||
"syntax_highlighter"
|
||||
]
|
||||
end
|
||||
|
||||
@highlighter = begin
|
||||
if @config.key?("enable_coderay") && @config["enable_coderay"]
|
||||
Jekyll::Deprecator.deprecation_message(
|
||||
"You are using 'enable_coderay', " \
|
||||
"use syntax_highlighter: coderay in your configuration file."
|
||||
)
|
||||
|
||||
"coderay"
|
||||
else
|
||||
@main_fallback_highlighter
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def strip_coderay_prefix(hash)
|
||||
hash.each_with_object({}) do |(key, val), hsh|
|
||||
cleaned_key = key.to_s.gsub(%r!\Acoderay_!, "")
|
||||
|
||||
if key != cleaned_key
|
||||
Jekyll::Deprecator.deprecation_message(
|
||||
"You are using '#{key}'. Normalizing to #{cleaned_key}."
|
||||
)
|
||||
end
|
||||
|
||||
hsh[cleaned_key] = val
|
||||
end
|
||||
end
|
||||
|
||||
# If our highlighter is CodeRay we go in to merge the CodeRay defaults
|
||||
# with your "coderay" key if it's there, deprecating it in the
|
||||
# process of you using it.
|
||||
def modernize_coderay_config
|
||||
unless @config["coderay"].empty?
|
||||
Jekyll::Deprecator.deprecation_message(
|
||||
"You are using 'kramdown.coderay' in your configuration, " \
|
||||
"please use 'syntax_highlighter_opts' instead."
|
||||
)
|
||||
|
||||
@config["syntax_highlighter_opts"] = begin
|
||||
strip_coderay_prefix(
|
||||
@config["syntax_highlighter_opts"] \
|
||||
.merge(CODERAY_DEFAULTS) \
|
||||
.merge(@config["coderay"])
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
70
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/converters/smartypants.rb
vendored
Normal file
70
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/converters/smartypants.rb
vendored
Normal file
@@ -0,0 +1,70 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Kramdown
|
||||
module Parser
|
||||
class SmartyPants < Kramdown::Parser::Kramdown
|
||||
def initialize(source, options)
|
||||
super
|
||||
@block_parsers = [:block_html, :content]
|
||||
@span_parsers = [:smart_quotes, :html_entity, :typographic_syms, :span_html]
|
||||
end
|
||||
|
||||
def parse_content
|
||||
add_text @src.scan(%r!\A.*\n!)
|
||||
end
|
||||
define_parser(:content, %r!\A!)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
module Jekyll
|
||||
module Converters
|
||||
# SmartyPants converter.
|
||||
# For more info on converters see https://jekyllrb.com/docs/plugins/converters/
|
||||
class SmartyPants < Converter
|
||||
safe true
|
||||
priority :low
|
||||
|
||||
def initialize(config)
|
||||
Jekyll::External.require_with_graceful_fail "kramdown" unless defined?(Kramdown)
|
||||
@config = config["kramdown"].dup || {}
|
||||
@config[:input] = :SmartyPants
|
||||
end
|
||||
|
||||
# Does the given extension match this converter's list of acceptable extensions?
|
||||
# Takes one argument: the file's extension (including the dot).
|
||||
#
|
||||
# ext - The String extension to check.
|
||||
#
|
||||
# Returns true if it matches, false otherwise.
|
||||
def matches(_ext)
|
||||
false
|
||||
end
|
||||
|
||||
# Public: The extension to be given to the output file (including the dot).
|
||||
#
|
||||
# ext - The String extension or original file.
|
||||
#
|
||||
# Returns The String output file extension.
|
||||
def output_ext(_ext)
|
||||
nil
|
||||
end
|
||||
|
||||
# Logic to do the content conversion.
|
||||
#
|
||||
# content - String content of file (without front matter).
|
||||
#
|
||||
# Returns a String of the converted content.
|
||||
def convert(content)
|
||||
document = Kramdown::Document.new(content, @config)
|
||||
html_output = document.to_html.chomp
|
||||
if @config["show_warnings"]
|
||||
document.warnings.each do |warning|
|
||||
Jekyll.logger.warn "Kramdown warning:", warning.sub(%r!^Warning:\s+!, "")
|
||||
end
|
||||
end
|
||||
html_output
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
260
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/convertible.rb
vendored
Normal file
260
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/convertible.rb
vendored
Normal file
@@ -0,0 +1,260 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
# Convertible provides methods for converting a pagelike item
|
||||
# from a certain type of markup into actual content
|
||||
#
|
||||
# Requires
|
||||
# self.site -> Jekyll::Site
|
||||
# self.content
|
||||
# self.content=
|
||||
# self.data=
|
||||
# self.ext=
|
||||
# self.output=
|
||||
# self.name
|
||||
# self.path
|
||||
# self.type -> :page, :post or :draft
|
||||
|
||||
module Jekyll
|
||||
module Convertible
|
||||
# Returns the contents as a String.
|
||||
def to_s
|
||||
content || ""
|
||||
end
|
||||
|
||||
# Whether the file is published or not, as indicated in YAML front-matter
|
||||
def published?
|
||||
!(data.key?("published") && data["published"] == false)
|
||||
end
|
||||
|
||||
# Read the YAML frontmatter.
|
||||
#
|
||||
# base - The String path to the dir containing the file.
|
||||
# name - The String filename of the file.
|
||||
# opts - optional parameter to File.read, default at site configs
|
||||
#
|
||||
# Returns nothing.
|
||||
# rubocop:disable Metrics/AbcSize
|
||||
def read_yaml(base, name, opts = {})
|
||||
filename = @path || site.in_source_dir(base, name)
|
||||
Jekyll.logger.debug "Reading:", relative_path
|
||||
|
||||
begin
|
||||
self.content = File.read(filename, **Utils.merged_file_read_opts(site, opts))
|
||||
if content =~ Document::YAML_FRONT_MATTER_REGEXP
|
||||
self.content = Regexp.last_match.post_match
|
||||
self.data = SafeYAML.load(Regexp.last_match(1))
|
||||
end
|
||||
rescue Psych::SyntaxError => e
|
||||
Jekyll.logger.warn "YAML Exception reading #{filename}: #{e.message}"
|
||||
raise e if site.config["strict_front_matter"]
|
||||
rescue StandardError => e
|
||||
Jekyll.logger.warn "Error reading file #{filename}: #{e.message}"
|
||||
raise e if site.config["strict_front_matter"]
|
||||
end
|
||||
|
||||
self.data ||= {}
|
||||
|
||||
validate_data! filename
|
||||
validate_permalink! filename
|
||||
|
||||
self.data
|
||||
end
|
||||
# rubocop:enable Metrics/AbcSize
|
||||
|
||||
def validate_data!(filename)
|
||||
unless self.data.is_a?(Hash)
|
||||
raise Errors::InvalidYAMLFrontMatterError,
|
||||
"Invalid YAML front matter in #{filename}"
|
||||
end
|
||||
end
|
||||
|
||||
def validate_permalink!(filename)
|
||||
if self.data["permalink"] == ""
|
||||
raise Errors::InvalidPermalinkError, "Invalid permalink in #{filename}"
|
||||
end
|
||||
end
|
||||
|
||||
# Transform the contents based on the content type.
|
||||
#
|
||||
# Returns the transformed contents.
|
||||
def transform
|
||||
renderer.convert(content)
|
||||
end
|
||||
|
||||
# Determine the extension depending on content_type.
|
||||
#
|
||||
# Returns the String extension for the output file.
|
||||
# e.g. ".html" for an HTML output file.
|
||||
def output_ext
|
||||
renderer.output_ext
|
||||
end
|
||||
|
||||
# Determine which converter to use based on this convertible's
|
||||
# extension.
|
||||
#
|
||||
# Returns the Converter instance.
|
||||
def converters
|
||||
renderer.converters
|
||||
end
|
||||
|
||||
# Render Liquid in the content
|
||||
#
|
||||
# content - the raw Liquid content to render
|
||||
# payload - the payload for Liquid
|
||||
# info - the info for Liquid
|
||||
#
|
||||
# Returns the converted content
|
||||
def render_liquid(content, payload, info, path)
|
||||
renderer.render_liquid(content, payload, info, path)
|
||||
end
|
||||
|
||||
# Convert this Convertible's data to a Hash suitable for use by Liquid.
|
||||
#
|
||||
# Returns the Hash representation of this Convertible.
|
||||
def to_liquid(attrs = nil)
|
||||
further_data = attribute_hash(attrs || self.class::ATTRIBUTES_FOR_LIQUID)
|
||||
Utils.deep_merge_hashes defaults, Utils.deep_merge_hashes(data, further_data)
|
||||
end
|
||||
|
||||
# The type of a document,
|
||||
# i.e., its classname downcase'd and to_sym'd.
|
||||
#
|
||||
# Returns the type of self.
|
||||
def type
|
||||
:pages if is_a?(Page)
|
||||
end
|
||||
|
||||
# returns the owner symbol for hook triggering
|
||||
def hook_owner
|
||||
:pages if is_a?(Page)
|
||||
end
|
||||
|
||||
# Determine whether the document is an asset file.
|
||||
# Asset files include CoffeeScript files and Sass/SCSS files.
|
||||
#
|
||||
# Returns true if the extname belongs to the set of extensions
|
||||
# that asset files use.
|
||||
def asset_file?
|
||||
sass_file? || coffeescript_file?
|
||||
end
|
||||
|
||||
# Determine whether the document is a Sass file.
|
||||
#
|
||||
# Returns true if extname == .sass or .scss, false otherwise.
|
||||
def sass_file?
|
||||
Jekyll::Document::SASS_FILE_EXTS.include?(ext)
|
||||
end
|
||||
|
||||
# Determine whether the document is a CoffeeScript file.
|
||||
#
|
||||
# Returns true if extname == .coffee, false otherwise.
|
||||
def coffeescript_file?
|
||||
ext == ".coffee"
|
||||
end
|
||||
|
||||
# Determine whether the file should be rendered with Liquid.
|
||||
#
|
||||
# Returns true if the file has Liquid Tags or Variables, false otherwise.
|
||||
def render_with_liquid?
|
||||
return false if data["render_with_liquid"] == false
|
||||
|
||||
Jekyll::Utils.has_liquid_construct?(content)
|
||||
end
|
||||
|
||||
# Determine whether the file should be placed into layouts.
|
||||
#
|
||||
# Returns false if the document is an asset file or if the front matter
|
||||
# specifies `layout: none`
|
||||
def place_in_layout?
|
||||
!(asset_file? || no_layout?)
|
||||
end
|
||||
|
||||
# Checks if the layout specified in the document actually exists
|
||||
#
|
||||
# layout - the layout to check
|
||||
#
|
||||
# Returns true if the layout is invalid, false if otherwise
|
||||
def invalid_layout?(layout)
|
||||
!data["layout"].nil? && layout.nil? && !(is_a? Jekyll::Excerpt)
|
||||
end
|
||||
|
||||
# Recursively render layouts
|
||||
#
|
||||
# layouts - a list of the layouts
|
||||
# payload - the payload for Liquid
|
||||
# info - the info for Liquid
|
||||
#
|
||||
# Returns nothing
|
||||
def render_all_layouts(layouts, payload, info)
|
||||
renderer.layouts = layouts
|
||||
self.output = renderer.place_in_layouts(output, payload, info)
|
||||
ensure
|
||||
@renderer = nil # this will allow the modifications above to disappear
|
||||
end
|
||||
|
||||
# Add any necessary layouts to this convertible document.
|
||||
#
|
||||
# payload - The site payload Drop or Hash.
|
||||
# layouts - A Hash of {"name" => "layout"}.
|
||||
#
|
||||
# Returns nothing.
|
||||
def do_layout(payload, layouts)
|
||||
self.output = renderer.tap do |doc_renderer|
|
||||
doc_renderer.layouts = layouts
|
||||
doc_renderer.payload = payload
|
||||
end.run
|
||||
|
||||
Jekyll.logger.debug "Post-Render Hooks:", relative_path
|
||||
Jekyll::Hooks.trigger hook_owner, :post_render, self
|
||||
ensure
|
||||
@renderer = nil # this will allow the modifications above to disappear
|
||||
end
|
||||
|
||||
# Write the generated page file to the destination directory.
|
||||
#
|
||||
# dest - The String path to the destination dir.
|
||||
#
|
||||
# Returns nothing.
|
||||
def write(dest)
|
||||
path = destination(dest)
|
||||
FileUtils.mkdir_p(File.dirname(path))
|
||||
Jekyll.logger.debug "Writing:", path
|
||||
File.write(path, output, :mode => "wb")
|
||||
Jekyll::Hooks.trigger hook_owner, :post_write, self
|
||||
end
|
||||
|
||||
# Accessor for data properties by Liquid.
|
||||
#
|
||||
# property - The String name of the property to retrieve.
|
||||
#
|
||||
# Returns the String value or nil if the property isn't included.
|
||||
def [](property)
|
||||
if self.class::ATTRIBUTES_FOR_LIQUID.include?(property)
|
||||
send(property)
|
||||
else
|
||||
data[property]
|
||||
end
|
||||
end
|
||||
|
||||
def renderer
|
||||
@renderer ||= Jekyll::Renderer.new(site, self)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def defaults
|
||||
@defaults ||= site.frontmatter_defaults.all(relative_path, type)
|
||||
end
|
||||
|
||||
def attribute_hash(attrs)
|
||||
@attribute_hash ||= {}
|
||||
@attribute_hash[attrs] ||= attrs.each_with_object({}) do |attribute, hsh|
|
||||
hsh[attribute] = send(attribute)
|
||||
end
|
||||
end
|
||||
|
||||
def no_layout?
|
||||
data["layout"] == "none"
|
||||
end
|
||||
end
|
||||
end
|
||||
50
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/deprecator.rb
vendored
Normal file
50
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/deprecator.rb
vendored
Normal file
@@ -0,0 +1,50 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Jekyll
|
||||
module Deprecator
|
||||
extend self
|
||||
|
||||
def process(args)
|
||||
arg_is_present? args, "--server", "The --server command has been replaced by the \
|
||||
'serve' subcommand."
|
||||
arg_is_present? args, "--serve", "The --serve command has been replaced by the \
|
||||
'serve' subcommand."
|
||||
arg_is_present? args, "--no-server", "To build Jekyll without launching a server, \
|
||||
use the 'build' subcommand."
|
||||
arg_is_present? args, "--auto", "The switch '--auto' has been replaced with \
|
||||
'--watch'."
|
||||
arg_is_present? args, "--no-auto", "To disable auto-replication, simply leave off \
|
||||
the '--watch' switch."
|
||||
arg_is_present? args, "--pygments", "The 'pygments'settings has been removed in \
|
||||
favour of 'highlighter'."
|
||||
arg_is_present? args, "--paginate", "The 'paginate' setting can only be set in \
|
||||
your config files."
|
||||
arg_is_present? args, "--url", "The 'url' setting can only be set in your \
|
||||
config files."
|
||||
no_subcommand(args)
|
||||
end
|
||||
|
||||
def no_subcommand(args)
|
||||
unless args.empty? ||
|
||||
args.first !~ %r(!/^--/!) || %w(--help --version).include?(args.first)
|
||||
deprecation_message "Jekyll now uses subcommands instead of just switches. \
|
||||
Run `jekyll help` to find out more."
|
||||
abort
|
||||
end
|
||||
end
|
||||
|
||||
def arg_is_present?(args, deprecated_argument, message)
|
||||
deprecation_message(message) if args.include?(deprecated_argument)
|
||||
end
|
||||
|
||||
def deprecation_message(message)
|
||||
Jekyll.logger.warn "Deprecation:", message
|
||||
end
|
||||
|
||||
def defaults_deprecate_type(old, current)
|
||||
Jekyll.logger.warn "Defaults:", "The '#{old}' type has become '#{current}'."
|
||||
Jekyll.logger.warn "Defaults:", "Please update your front-matter defaults to use \
|
||||
'type: #{current}'."
|
||||
end
|
||||
end
|
||||
end
|
||||
544
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/document.rb
vendored
Normal file
544
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/document.rb
vendored
Normal file
@@ -0,0 +1,544 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Jekyll
|
||||
class Document
|
||||
include Comparable
|
||||
extend Forwardable
|
||||
|
||||
attr_reader :path, :site, :extname, :collection, :type
|
||||
attr_accessor :content, :output
|
||||
|
||||
def_delegator :self, :read_post_data, :post_read
|
||||
|
||||
YAML_FRONT_MATTER_REGEXP = %r!\A(---\s*\n.*?\n?)^((---|\.\.\.)\s*$\n?)!m.freeze
|
||||
DATELESS_FILENAME_MATCHER = %r!^(?:.+/)*(.*)(\.[^.]+)$!.freeze
|
||||
DATE_FILENAME_MATCHER = %r!^(?>.+/)*?(\d{2,4}-\d{1,2}-\d{1,2})-([^/]*)(\.[^.]+)$!.freeze
|
||||
|
||||
SASS_FILE_EXTS = %w(.sass .scss).freeze
|
||||
YAML_FILE_EXTS = %w(.yaml .yml).freeze
|
||||
|
||||
#
|
||||
|
||||
# Class-wide cache to stash and retrieve regexp to detect "super-directories"
|
||||
# of a particular Jekyll::Document object.
|
||||
#
|
||||
# dirname - The *special directory* for the Document.
|
||||
# e.g. "_posts" or "_drafts" for Documents from the `site.posts` collection.
|
||||
def self.superdirs_regex(dirname)
|
||||
@superdirs_regex ||= {}
|
||||
@superdirs_regex[dirname] ||= %r!#{dirname}.*!
|
||||
end
|
||||
|
||||
#
|
||||
|
||||
# Create a new Document.
|
||||
#
|
||||
# path - the path to the file
|
||||
# relations - a hash with keys :site and :collection, the values of which
|
||||
# are the Jekyll::Site and Jekyll::Collection to which this
|
||||
# Document belong.
|
||||
#
|
||||
# Returns nothing.
|
||||
def initialize(path, relations = {})
|
||||
@site = relations[:site]
|
||||
@path = path
|
||||
@extname = File.extname(path)
|
||||
@collection = relations[:collection]
|
||||
@type = @collection.label.to_sym
|
||||
|
||||
@has_yaml_header = nil
|
||||
|
||||
if draft?
|
||||
categories_from_path("_drafts")
|
||||
else
|
||||
categories_from_path(collection.relative_directory)
|
||||
end
|
||||
|
||||
data.default_proc = proc do |_, key|
|
||||
site.frontmatter_defaults.find(relative_path, type, key)
|
||||
end
|
||||
|
||||
trigger_hooks(:post_init)
|
||||
end
|
||||
|
||||
# Fetch the Document's data.
|
||||
#
|
||||
# Returns a Hash containing the data. An empty hash is returned if
|
||||
# no data was read.
|
||||
def data
|
||||
@data ||= {}
|
||||
end
|
||||
|
||||
# Merge some data in with this document's data.
|
||||
#
|
||||
# Returns the merged data.
|
||||
def merge_data!(other, source: "YAML front matter")
|
||||
merge_categories!(other)
|
||||
Utils.deep_merge_hashes!(data, other)
|
||||
merge_date!(source)
|
||||
data
|
||||
end
|
||||
|
||||
# Returns the document date. If metadata is not present then calculates it
|
||||
# based on Jekyll::Site#time or the document file modification time.
|
||||
#
|
||||
# Return document date string.
|
||||
def date
|
||||
data["date"] ||= (draft? ? source_file_mtime : site.time)
|
||||
end
|
||||
|
||||
# Return document file modification time in the form of a Time object.
|
||||
#
|
||||
# Return document file modification Time object.
|
||||
def source_file_mtime
|
||||
File.mtime(path)
|
||||
end
|
||||
|
||||
# Returns whether the document is a draft. This is only the case if
|
||||
# the document is in the 'posts' collection but in a different
|
||||
# directory than '_posts'.
|
||||
#
|
||||
# Returns whether the document is a draft.
|
||||
def draft?
|
||||
data["draft"] ||= relative_path.index(collection.relative_directory).nil? &&
|
||||
collection.label == "posts"
|
||||
end
|
||||
|
||||
# The path to the document, relative to the collections_dir.
|
||||
#
|
||||
# Returns a String path which represents the relative path from the collections_dir
|
||||
# to this document.
|
||||
def relative_path
|
||||
@relative_path ||= path.sub("#{site.collections_path}/", "")
|
||||
end
|
||||
|
||||
# The output extension of the document.
|
||||
#
|
||||
# Returns the output extension
|
||||
def output_ext
|
||||
renderer.output_ext
|
||||
end
|
||||
|
||||
# The base filename of the document, without the file extname.
|
||||
#
|
||||
# Returns the basename without the file extname.
|
||||
def basename_without_ext
|
||||
@basename_without_ext ||= File.basename(path, ".*")
|
||||
end
|
||||
|
||||
# The base filename of the document.
|
||||
#
|
||||
# Returns the base filename of the document.
|
||||
def basename
|
||||
@basename ||= File.basename(path)
|
||||
end
|
||||
|
||||
def renderer
|
||||
@renderer ||= Jekyll::Renderer.new(site, self)
|
||||
end
|
||||
|
||||
# Produces a "cleaned" relative path.
|
||||
# The "cleaned" relative path is the relative path without the extname
|
||||
# and with the collection's directory removed as well.
|
||||
# This method is useful when building the URL of the document.
|
||||
#
|
||||
# NOTE: `String#gsub` removes all trailing periods (in comparison to `String#chomp`)
|
||||
#
|
||||
# Examples:
|
||||
# When relative_path is "_methods/site/generate...md":
|
||||
# cleaned_relative_path
|
||||
# # => "/site/generate"
|
||||
#
|
||||
# Returns the cleaned relative path of the document.
|
||||
def cleaned_relative_path
|
||||
@cleaned_relative_path ||=
|
||||
relative_path[0..-extname.length - 1]
|
||||
.sub(collection.relative_directory, "")
|
||||
.gsub(%r!\.*\z!, "")
|
||||
end
|
||||
|
||||
# Determine whether the document is a YAML file.
|
||||
#
|
||||
# Returns true if the extname is either .yml or .yaml, false otherwise.
|
||||
def yaml_file?
|
||||
YAML_FILE_EXTS.include?(extname)
|
||||
end
|
||||
|
||||
# Determine whether the document is an asset file.
|
||||
# Asset files include CoffeeScript files and Sass/SCSS files.
|
||||
#
|
||||
# Returns true if the extname belongs to the set of extensions
|
||||
# that asset files use.
|
||||
def asset_file?
|
||||
sass_file? || coffeescript_file?
|
||||
end
|
||||
|
||||
# Determine whether the document is a Sass file.
|
||||
#
|
||||
# Returns true if extname == .sass or .scss, false otherwise.
|
||||
def sass_file?
|
||||
SASS_FILE_EXTS.include?(extname)
|
||||
end
|
||||
|
||||
# Determine whether the document is a CoffeeScript file.
|
||||
#
|
||||
# Returns true if extname == .coffee, false otherwise.
|
||||
def coffeescript_file?
|
||||
extname == ".coffee"
|
||||
end
|
||||
|
||||
# Determine whether the file should be rendered with Liquid.
|
||||
#
|
||||
# Returns false if the document is either an asset file or a yaml file,
|
||||
# or if the document doesn't contain any Liquid Tags or Variables,
|
||||
# true otherwise.
|
||||
def render_with_liquid?
|
||||
return false if data["render_with_liquid"] == false
|
||||
|
||||
!(coffeescript_file? || yaml_file? || !Utils.has_liquid_construct?(content))
|
||||
end
|
||||
|
||||
# Determine whether the file should be rendered with a layout.
|
||||
#
|
||||
# Returns true if the Front Matter specifies that `layout` is set to `none`.
|
||||
def no_layout?
|
||||
data["layout"] == "none"
|
||||
end
|
||||
|
||||
# Determine whether the file should be placed into layouts.
|
||||
#
|
||||
# Returns false if the document is set to `layouts: none`, or is either an
|
||||
# asset file or a yaml file. Returns true otherwise.
|
||||
def place_in_layout?
|
||||
!(asset_file? || yaml_file? || no_layout?)
|
||||
end
|
||||
|
||||
# The URL template where the document would be accessible.
|
||||
#
|
||||
# Returns the URL template for the document.
|
||||
def url_template
|
||||
collection.url_template
|
||||
end
|
||||
|
||||
# Construct a Hash of key-value pairs which contain a mapping between
|
||||
# a key in the URL template and the corresponding value for this document.
|
||||
#
|
||||
# Returns the Hash of key-value pairs for replacement in the URL.
|
||||
def url_placeholders
|
||||
@url_placeholders ||= Drops::UrlDrop.new(self)
|
||||
end
|
||||
|
||||
# The permalink for this Document.
|
||||
# Permalink is set via the data Hash.
|
||||
#
|
||||
# Returns the permalink or nil if no permalink was set in the data.
|
||||
def permalink
|
||||
data && data.is_a?(Hash) && data["permalink"]
|
||||
end
|
||||
|
||||
# The computed URL for the document. See `Jekyll::URL#to_s` for more details.
|
||||
#
|
||||
# Returns the computed URL for the document.
|
||||
def url
|
||||
@url ||= URL.new(
|
||||
:template => url_template,
|
||||
:placeholders => url_placeholders,
|
||||
:permalink => permalink
|
||||
).to_s
|
||||
end
|
||||
|
||||
def [](key)
|
||||
data[key]
|
||||
end
|
||||
|
||||
# The full path to the output file.
|
||||
#
|
||||
# base_directory - the base path of the output directory
|
||||
#
|
||||
# Returns the full path to the output file of this document.
|
||||
def destination(base_directory)
|
||||
@destination ||= {}
|
||||
@destination[base_directory] ||= begin
|
||||
path = site.in_dest_dir(base_directory, URL.unescape_path(url))
|
||||
if url.end_with? "/"
|
||||
path = File.join(path, "index.html")
|
||||
else
|
||||
path << output_ext unless path.end_with? output_ext
|
||||
end
|
||||
path
|
||||
end
|
||||
end
|
||||
|
||||
# Write the generated Document file to the destination directory.
|
||||
#
|
||||
# dest - The String path to the destination dir.
|
||||
#
|
||||
# Returns nothing.
|
||||
def write(dest)
|
||||
path = destination(dest)
|
||||
FileUtils.mkdir_p(File.dirname(path))
|
||||
Jekyll.logger.debug "Writing:", path
|
||||
File.write(path, output, :mode => "wb")
|
||||
|
||||
trigger_hooks(:post_write)
|
||||
end
|
||||
|
||||
# Whether the file is published or not, as indicated in YAML front-matter
|
||||
#
|
||||
# Returns 'false' if the 'published' key is specified in the
|
||||
# YAML front-matter and is 'false'. Otherwise returns 'true'.
|
||||
def published?
|
||||
!(data.key?("published") && data["published"] == false)
|
||||
end
|
||||
|
||||
# Read in the file and assign the content and data based on the file contents.
|
||||
# Merge the frontmatter of the file with the frontmatter default
|
||||
# values
|
||||
#
|
||||
# Returns nothing.
|
||||
def read(opts = {})
|
||||
Jekyll.logger.debug "Reading:", relative_path
|
||||
|
||||
if yaml_file?
|
||||
@data = SafeYAML.load_file(path)
|
||||
else
|
||||
begin
|
||||
merge_defaults
|
||||
read_content(**opts)
|
||||
read_post_data
|
||||
rescue StandardError => e
|
||||
handle_read_error(e)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Create a Liquid-understandable version of this Document.
|
||||
#
|
||||
# Returns a Hash representing this Document's data.
|
||||
def to_liquid
|
||||
@to_liquid ||= Drops::DocumentDrop.new(self)
|
||||
end
|
||||
|
||||
# The inspect string for this document.
|
||||
# Includes the relative path and the collection label.
|
||||
#
|
||||
# Returns the inspect string for this document.
|
||||
def inspect
|
||||
"#<#{self.class} #{relative_path} collection=#{collection.label}>"
|
||||
end
|
||||
|
||||
# The string representation for this document.
|
||||
#
|
||||
# Returns the content of the document
|
||||
def to_s
|
||||
output || content || "NO CONTENT"
|
||||
end
|
||||
|
||||
# Compare this document against another document.
|
||||
# Comparison is a comparison between the 2 paths of the documents.
|
||||
#
|
||||
# Returns -1, 0, +1 or nil depending on whether this doc's path is less than,
|
||||
# equal or greater than the other doc's path. See String#<=> for more details.
|
||||
def <=>(other)
|
||||
return nil unless other.respond_to?(:data)
|
||||
|
||||
cmp = data["date"] <=> other.data["date"]
|
||||
cmp = path <=> other.path if cmp.nil? || cmp.zero?
|
||||
cmp
|
||||
end
|
||||
|
||||
# Determine whether this document should be written.
|
||||
# Based on the Collection to which it belongs.
|
||||
#
|
||||
# True if the document has a collection and if that collection's #write?
|
||||
# method returns true, and if the site's Publisher will publish the document.
|
||||
# False otherwise.
|
||||
#
|
||||
# rubocop:disable Naming/MemoizedInstanceVariableName
|
||||
def write?
|
||||
return @write_p if defined?(@write_p)
|
||||
|
||||
@write_p = collection&.write? && site.publisher.publish?(self)
|
||||
end
|
||||
# rubocop:enable Naming/MemoizedInstanceVariableName
|
||||
|
||||
# The Document excerpt_separator, from the YAML Front-Matter or site
|
||||
# default excerpt_separator value
|
||||
#
|
||||
# Returns the document excerpt_separator
|
||||
def excerpt_separator
|
||||
@excerpt_separator ||= (data["excerpt_separator"] || site.config["excerpt_separator"]).to_s
|
||||
end
|
||||
|
||||
# Whether to generate an excerpt
|
||||
#
|
||||
# Returns true if the excerpt separator is configured.
|
||||
def generate_excerpt?
|
||||
!excerpt_separator.empty?
|
||||
end
|
||||
|
||||
def next_doc
|
||||
pos = collection.docs.index { |post| post.equal?(self) }
|
||||
collection.docs[pos + 1] if pos && pos < collection.docs.length - 1
|
||||
end
|
||||
|
||||
def previous_doc
|
||||
pos = collection.docs.index { |post| post.equal?(self) }
|
||||
collection.docs[pos - 1] if pos && pos.positive?
|
||||
end
|
||||
|
||||
def trigger_hooks(hook_name, *args)
|
||||
Jekyll::Hooks.trigger collection.label.to_sym, hook_name, self, *args if collection
|
||||
Jekyll::Hooks.trigger :documents, hook_name, self, *args
|
||||
end
|
||||
|
||||
def id
|
||||
@id ||= File.join(File.dirname(url), (data["slug"] || basename_without_ext).to_s)
|
||||
end
|
||||
|
||||
# Calculate related posts.
|
||||
#
|
||||
# Returns an Array of related Posts.
|
||||
def related_posts
|
||||
@related_posts ||= Jekyll::RelatedPosts.new(self).build
|
||||
end
|
||||
|
||||
# Override of method_missing to check in @data for the key.
|
||||
def method_missing(method, *args, &blck)
|
||||
if data.key?(method.to_s)
|
||||
Jekyll::Deprecator.deprecation_message "Document##{method} is now a key "\
|
||||
"in the #data hash."
|
||||
Jekyll::Deprecator.deprecation_message "Called by #{caller(0..0)}."
|
||||
data[method.to_s]
|
||||
else
|
||||
super
|
||||
end
|
||||
end
|
||||
|
||||
def respond_to_missing?(method, *)
|
||||
data.key?(method.to_s) || super
|
||||
end
|
||||
|
||||
# Add superdirectories of the special_dir to categories.
|
||||
# In the case of es/_posts, 'es' is added as a category.
|
||||
# In the case of _posts/es, 'es' is NOT added as a category.
|
||||
#
|
||||
# Returns nothing.
|
||||
def categories_from_path(special_dir)
|
||||
if relative_path.start_with?(special_dir)
|
||||
superdirs = []
|
||||
else
|
||||
superdirs = relative_path.sub(Document.superdirs_regex(special_dir), "")
|
||||
superdirs = superdirs.split(File::SEPARATOR)
|
||||
superdirs.reject! { |c| c.empty? || c == special_dir || c == basename }
|
||||
end
|
||||
|
||||
merge_data!({ "categories" => superdirs }, :source => "file path")
|
||||
end
|
||||
|
||||
def populate_categories
|
||||
categories = Array(data["categories"]) + Utils.pluralized_array_from_hash(
|
||||
data, "category", "categories"
|
||||
)
|
||||
categories.map!(&:to_s)
|
||||
categories.flatten!
|
||||
categories.uniq!
|
||||
|
||||
merge_data!({ "categories" => categories })
|
||||
end
|
||||
|
||||
def populate_tags
|
||||
tags = Utils.pluralized_array_from_hash(data, "tag", "tags")
|
||||
tags.flatten!
|
||||
|
||||
merge_data!({ "tags" => tags })
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def merge_categories!(other)
|
||||
if other.key?("categories") && !other["categories"].nil?
|
||||
other["categories"] = other["categories"].split if other["categories"].is_a?(String)
|
||||
|
||||
if data["categories"].is_a?(Array)
|
||||
other["categories"] = data["categories"] | other["categories"]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def merge_date!(source)
|
||||
if data.key?("date")
|
||||
data["date"] = Utils.parse_date(
|
||||
data["date"].to_s,
|
||||
"Document '#{relative_path}' does not have a valid date in the #{source}."
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
def merge_defaults
|
||||
defaults = @site.frontmatter_defaults.all(relative_path, type)
|
||||
merge_data!(defaults, :source => "front matter defaults") unless defaults.empty?
|
||||
end
|
||||
|
||||
def read_content(**opts)
|
||||
self.content = File.read(path, **Utils.merged_file_read_opts(site, opts))
|
||||
if content =~ YAML_FRONT_MATTER_REGEXP
|
||||
self.content = Regexp.last_match.post_match
|
||||
data_file = SafeYAML.load(Regexp.last_match(1))
|
||||
merge_data!(data_file, :source => "YAML front matter") if data_file
|
||||
end
|
||||
end
|
||||
|
||||
def read_post_data
|
||||
populate_title
|
||||
populate_categories
|
||||
populate_tags
|
||||
generate_excerpt
|
||||
end
|
||||
|
||||
def handle_read_error(error)
|
||||
if error.is_a? Psych::SyntaxError
|
||||
Jekyll.logger.error "Error:", "YAML Exception reading #{path}: #{error.message}"
|
||||
else
|
||||
Jekyll.logger.error "Error:", "could not read file #{path}: #{error.message}"
|
||||
end
|
||||
|
||||
if site.config["strict_front_matter"] || error.is_a?(Jekyll::Errors::FatalException)
|
||||
raise error
|
||||
end
|
||||
end
|
||||
|
||||
def populate_title
|
||||
if relative_path =~ DATE_FILENAME_MATCHER
|
||||
date, slug, ext = Regexp.last_match.captures
|
||||
modify_date(date)
|
||||
elsif relative_path =~ DATELESS_FILENAME_MATCHER
|
||||
slug, ext = Regexp.last_match.captures
|
||||
end
|
||||
# `slug` will be nil for documents without an extension since the regex patterns
|
||||
# above tests for an extension as well.
|
||||
# In such cases, assign `basename_without_ext` as the slug.
|
||||
slug ||= basename_without_ext
|
||||
|
||||
# slugs shouldn't end with a period
|
||||
# `String#gsub!` removes all trailing periods (in comparison to `String#chomp!`)
|
||||
slug.gsub!(%r!\.*\z!, "")
|
||||
|
||||
# Try to ensure the user gets a title.
|
||||
data["title"] ||= Utils.titleize_slug(slug)
|
||||
# Only overwrite slug & ext if they aren't specified.
|
||||
data["slug"] ||= slug
|
||||
data["ext"] ||= ext
|
||||
end
|
||||
|
||||
def modify_date(date)
|
||||
if !data["date"] || data["date"].to_i == site.time.to_i
|
||||
merge_data!({ "date" => date }, :source => "filename")
|
||||
end
|
||||
end
|
||||
|
||||
def generate_excerpt
|
||||
data["excerpt"] ||= Jekyll::Excerpt.new(self) if generate_excerpt?
|
||||
end
|
||||
end
|
||||
end
|
||||
20
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/drops/collection_drop.rb
vendored
Normal file
20
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/drops/collection_drop.rb
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Jekyll
|
||||
module Drops
|
||||
class CollectionDrop < Drop
|
||||
extend Forwardable
|
||||
|
||||
mutable false
|
||||
|
||||
delegate_method_as :write?, :output
|
||||
delegate_methods :label, :docs, :files, :directory, :relative_directory
|
||||
|
||||
private delegate_method_as :metadata, :fallback_data
|
||||
|
||||
def to_s
|
||||
docs.to_s
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
70
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/drops/document_drop.rb
vendored
Normal file
70
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/drops/document_drop.rb
vendored
Normal file
@@ -0,0 +1,70 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Jekyll
|
||||
module Drops
|
||||
class DocumentDrop < Drop
|
||||
extend Forwardable
|
||||
|
||||
NESTED_OBJECT_FIELD_BLACKLIST = %w(
|
||||
content output excerpt next previous
|
||||
).freeze
|
||||
|
||||
mutable false
|
||||
|
||||
delegate_method_as :relative_path, :path
|
||||
private delegate_method_as :data, :fallback_data
|
||||
|
||||
delegate_methods :id, :output, :content, :to_s, :relative_path, :url, :date
|
||||
data_delegators "title", "categories", "tags"
|
||||
|
||||
def collection
|
||||
@obj.collection.label
|
||||
end
|
||||
|
||||
def excerpt
|
||||
fallback_data["excerpt"].to_s
|
||||
end
|
||||
|
||||
def <=>(other)
|
||||
return nil unless other.is_a? DocumentDrop
|
||||
|
||||
cmp = self["date"] <=> other["date"]
|
||||
cmp = self["path"] <=> other["path"] if cmp.nil? || cmp.zero?
|
||||
cmp
|
||||
end
|
||||
|
||||
def previous
|
||||
@obj.previous_doc.to_liquid
|
||||
end
|
||||
|
||||
def next
|
||||
@obj.next_doc.to_liquid
|
||||
end
|
||||
|
||||
# Generate a Hash for use in generating JSON.
|
||||
# This is useful if fields need to be cleared before the JSON can generate.
|
||||
#
|
||||
# state - the JSON::State object which determines the state of current processing.
|
||||
#
|
||||
# Returns a Hash ready for JSON generation.
|
||||
def hash_for_json(state = nil)
|
||||
to_h.tap do |hash|
|
||||
if state && state.depth >= 2
|
||||
hash["previous"] = collapse_document(hash["previous"]) if hash["previous"]
|
||||
hash["next"] = collapse_document(hash["next"]) if hash["next"]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Generate a Hash which breaks the recursive chain.
|
||||
# Certain fields which are normally available are omitted.
|
||||
#
|
||||
# Returns a Hash with only non-recursive fields present.
|
||||
def collapse_document(doc)
|
||||
doc.keys.each_with_object({}) do |(key, _), result|
|
||||
result[key] = doc[key] unless NESTED_OBJECT_FIELD_BLACKLIST.include?(key)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
293
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/drops/drop.rb
vendored
Normal file
293
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/drops/drop.rb
vendored
Normal file
@@ -0,0 +1,293 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Jekyll
|
||||
module Drops
|
||||
class Drop < Liquid::Drop
|
||||
include Enumerable
|
||||
|
||||
NON_CONTENT_METHODS = [:fallback_data, :collapse_document].freeze
|
||||
NON_CONTENT_METHOD_NAMES = NON_CONTENT_METHODS.map(&:to_s).freeze
|
||||
private_constant :NON_CONTENT_METHOD_NAMES
|
||||
|
||||
# A private stash to avoid repeatedly generating the setter method name string for
|
||||
# a call to `Drops::Drop#[]=`.
|
||||
# The keys of the stash below have a very high probability of being called upon during
|
||||
# the course of various `Jekyll::Renderer#run` calls.
|
||||
SETTER_KEYS_STASH = {
|
||||
"content" => "content=",
|
||||
"layout" => "layout=",
|
||||
"page" => "page=",
|
||||
"paginator" => "paginator=",
|
||||
"highlighter_prefix" => "highlighter_prefix=",
|
||||
"highlighter_suffix" => "highlighter_suffix=",
|
||||
}.freeze
|
||||
private_constant :SETTER_KEYS_STASH
|
||||
|
||||
class << self
|
||||
# Get or set whether the drop class is mutable.
|
||||
# Mutability determines whether or not pre-defined fields may be
|
||||
# overwritten.
|
||||
#
|
||||
# is_mutable - Boolean set mutability of the class (default: nil)
|
||||
#
|
||||
# Returns the mutability of the class
|
||||
def mutable(is_mutable = nil)
|
||||
@is_mutable = is_mutable || false
|
||||
end
|
||||
|
||||
def mutable?
|
||||
@is_mutable
|
||||
end
|
||||
|
||||
# public delegation helper methods that calls onto Drop's instance
|
||||
# variable `@obj`.
|
||||
|
||||
# Generate private Drop instance_methods for each symbol in the given list.
|
||||
#
|
||||
# Returns nothing.
|
||||
def private_delegate_methods(*symbols)
|
||||
symbols.each { |symbol| private delegate_method(symbol) }
|
||||
nil
|
||||
end
|
||||
|
||||
# Generate public Drop instance_methods for each symbol in the given list.
|
||||
#
|
||||
# Returns nothing.
|
||||
def delegate_methods(*symbols)
|
||||
symbols.each { |symbol| delegate_method(symbol) }
|
||||
nil
|
||||
end
|
||||
|
||||
# Generate public Drop instance_method for given symbol that calls `@obj.<sym>`.
|
||||
#
|
||||
# Returns delegated method symbol.
|
||||
def delegate_method(symbol)
|
||||
define_method(symbol) { @obj.send(symbol) }
|
||||
end
|
||||
|
||||
# Generate public Drop instance_method named `delegate` that calls `@obj.<original>`.
|
||||
#
|
||||
# Returns delegated method symbol.
|
||||
def delegate_method_as(original, delegate)
|
||||
define_method(delegate) { @obj.send(original) }
|
||||
end
|
||||
|
||||
# Generate public Drop instance_methods for each string entry in the given list.
|
||||
# The generated method(s) access(es) `@obj`'s data hash.
|
||||
#
|
||||
# Returns nothing.
|
||||
def data_delegators(*strings)
|
||||
strings.each do |key|
|
||||
data_delegator(key) if key.is_a?(String)
|
||||
end
|
||||
nil
|
||||
end
|
||||
|
||||
# Generate public Drop instance_methods for given string `key`.
|
||||
# The generated method access(es) `@obj`'s data hash.
|
||||
#
|
||||
# Returns method symbol.
|
||||
def data_delegator(key)
|
||||
define_method(key.to_sym) { @obj.data[key] }
|
||||
end
|
||||
|
||||
# Array of stringified instance methods that do not end with the assignment operator.
|
||||
#
|
||||
# (<klass>.instance_methods always generates a new Array object so it can be mutated)
|
||||
#
|
||||
# Returns array of strings.
|
||||
def getter_method_names
|
||||
@getter_method_names ||= instance_methods.map!(&:to_s).tap do |list|
|
||||
list.reject! { |item| item.end_with?("=") }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Create a new Drop
|
||||
#
|
||||
# obj - the Jekyll Site, Collection, or Document required by the
|
||||
# drop.
|
||||
#
|
||||
# Returns nothing
|
||||
def initialize(obj)
|
||||
@obj = obj
|
||||
end
|
||||
|
||||
# Access a method in the Drop or a field in the underlying hash data.
|
||||
# If mutable, checks the mutations first. Then checks the methods,
|
||||
# and finally check the underlying hash (e.g. document front matter)
|
||||
# if all the previous places didn't match.
|
||||
#
|
||||
# key - the string key whose value to fetch
|
||||
#
|
||||
# Returns the value for the given key, or nil if none exists
|
||||
def [](key)
|
||||
if self.class.mutable? && mutations.key?(key)
|
||||
mutations[key]
|
||||
elsif self.class.invokable? key
|
||||
public_send key
|
||||
else
|
||||
fallback_data[key]
|
||||
end
|
||||
end
|
||||
alias_method :invoke_drop, :[]
|
||||
|
||||
# Set a field in the Drop. If mutable, sets in the mutations and
|
||||
# returns. If not mutable, checks first if it's trying to override a
|
||||
# Drop method and raises a DropMutationException if so. If not
|
||||
# mutable and the key is not a method on the Drop, then it sets the
|
||||
# key to the value in the underlying hash (e.g. document front
|
||||
# matter)
|
||||
#
|
||||
# key - the String key whose value to set
|
||||
# val - the Object to set the key's value to
|
||||
#
|
||||
# Returns the value the key was set to unless the Drop is not mutable
|
||||
# and the key matches a method in which case it raises a
|
||||
# DropMutationException.
|
||||
def []=(key, val)
|
||||
setter = SETTER_KEYS_STASH[key] || "#{key}="
|
||||
if respond_to?(setter)
|
||||
public_send(setter, val)
|
||||
elsif respond_to?(key.to_s)
|
||||
if self.class.mutable?
|
||||
mutations[key] = val
|
||||
else
|
||||
raise Errors::DropMutationException, "Key #{key} cannot be set in the drop."
|
||||
end
|
||||
else
|
||||
fallback_data[key] = val
|
||||
end
|
||||
end
|
||||
|
||||
# Generates a list of strings which correspond to content getter
|
||||
# methods.
|
||||
#
|
||||
# Returns an Array of strings which represent method-specific keys.
|
||||
def content_methods
|
||||
@content_methods ||= \
|
||||
self.class.getter_method_names \
|
||||
- Jekyll::Drops::Drop.getter_method_names \
|
||||
- NON_CONTENT_METHOD_NAMES
|
||||
end
|
||||
|
||||
# Check if key exists in Drop
|
||||
#
|
||||
# key - the string key whose value to fetch
|
||||
#
|
||||
# Returns true if the given key is present
|
||||
def key?(key)
|
||||
return false if key.nil?
|
||||
return true if self.class.mutable? && mutations.key?(key)
|
||||
|
||||
respond_to?(key) || fallback_data.key?(key)
|
||||
end
|
||||
|
||||
# Generates a list of keys with user content as their values.
|
||||
# This gathers up the Drop methods and keys of the mutations and
|
||||
# underlying data hashes and performs a set union to ensure a list
|
||||
# of unique keys for the Drop.
|
||||
#
|
||||
# Returns an Array of unique keys for content for the Drop.
|
||||
def keys
|
||||
(content_methods |
|
||||
mutations.keys |
|
||||
fallback_data.keys).flatten
|
||||
end
|
||||
|
||||
# Generate a Hash representation of the Drop by resolving each key's
|
||||
# value. It includes Drop methods, mutations, and the underlying object's
|
||||
# data. See the documentation for Drop#keys for more.
|
||||
#
|
||||
# Returns a Hash with all the keys and values resolved.
|
||||
def to_h
|
||||
keys.each_with_object({}) do |(key, _), result|
|
||||
result[key] = self[key]
|
||||
end
|
||||
end
|
||||
alias_method :to_hash, :to_h
|
||||
|
||||
# Inspect the drop's keys and values through a JSON representation
|
||||
# of its keys and values.
|
||||
#
|
||||
# Returns a pretty generation of the hash representation of the Drop.
|
||||
def inspect
|
||||
JSON.pretty_generate to_h
|
||||
end
|
||||
|
||||
# Generate a Hash for use in generating JSON.
|
||||
# This is useful if fields need to be cleared before the JSON can generate.
|
||||
#
|
||||
# Returns a Hash ready for JSON generation.
|
||||
def hash_for_json(*)
|
||||
to_h
|
||||
end
|
||||
|
||||
# Generate a JSON representation of the Drop.
|
||||
#
|
||||
# state - the JSON::State object which determines the state of current processing.
|
||||
#
|
||||
# Returns a JSON representation of the Drop in a String.
|
||||
def to_json(state = nil)
|
||||
JSON.generate(hash_for_json(state), state)
|
||||
end
|
||||
|
||||
# Collects all the keys and passes each to the block in turn.
|
||||
#
|
||||
# block - a block which accepts one argument, the key
|
||||
#
|
||||
# Returns nothing.
|
||||
def each_key(&block)
|
||||
keys.each(&block)
|
||||
end
|
||||
|
||||
def each
|
||||
each_key.each do |key|
|
||||
yield key, self[key]
|
||||
end
|
||||
end
|
||||
|
||||
def merge(other, &block)
|
||||
dup.tap do |me|
|
||||
if block.nil?
|
||||
me.merge!(other)
|
||||
else
|
||||
me.merge!(other, block)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def merge!(other)
|
||||
other.each_key do |key|
|
||||
if block_given?
|
||||
self[key] = yield key, self[key], other[key]
|
||||
else
|
||||
if Utils.mergable?(self[key]) && Utils.mergable?(other[key])
|
||||
self[key] = Utils.deep_merge_hashes(self[key], other[key])
|
||||
next
|
||||
end
|
||||
|
||||
self[key] = other[key] unless other[key].nil?
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Imitate Hash.fetch method in Drop
|
||||
#
|
||||
# Returns value if key is present in Drop, otherwise returns default value
|
||||
# KeyError is raised if key is not present and no default value given
|
||||
def fetch(key, default = nil, &block)
|
||||
return self[key] if key?(key)
|
||||
raise KeyError, %(key not found: "#{key}") if default.nil? && block.nil?
|
||||
return yield(key) unless block.nil?
|
||||
return default unless default.nil?
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def mutations
|
||||
@mutations ||= {}
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
19
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/drops/excerpt_drop.rb
vendored
Normal file
19
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/drops/excerpt_drop.rb
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Jekyll
|
||||
module Drops
|
||||
class ExcerptDrop < DocumentDrop
|
||||
def layout
|
||||
@obj.doc.data["layout"]
|
||||
end
|
||||
|
||||
def date
|
||||
@obj.doc.date
|
||||
end
|
||||
|
||||
def excerpt
|
||||
nil
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
32
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/drops/jekyll_drop.rb
vendored
Normal file
32
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/drops/jekyll_drop.rb
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Jekyll
|
||||
module Drops
|
||||
class JekyllDrop < Liquid::Drop
|
||||
class << self
|
||||
def global
|
||||
@global ||= JekyllDrop.new
|
||||
end
|
||||
end
|
||||
|
||||
def version
|
||||
Jekyll::VERSION
|
||||
end
|
||||
|
||||
def environment
|
||||
Jekyll.env
|
||||
end
|
||||
|
||||
def to_h
|
||||
@to_h ||= {
|
||||
"version" => version,
|
||||
"environment" => environment,
|
||||
}
|
||||
end
|
||||
|
||||
def to_json(state = nil)
|
||||
JSON.generate(to_h, state)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
66
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/drops/site_drop.rb
vendored
Normal file
66
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/drops/site_drop.rb
vendored
Normal file
@@ -0,0 +1,66 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Jekyll
|
||||
module Drops
|
||||
class SiteDrop < Drop
|
||||
extend Forwardable
|
||||
|
||||
mutable false
|
||||
|
||||
delegate_method_as :site_data, :data
|
||||
delegate_methods :time, :pages, :static_files, :tags, :categories
|
||||
|
||||
private delegate_method_as :config, :fallback_data
|
||||
|
||||
def [](key)
|
||||
if key != "posts" && @obj.collections.key?(key)
|
||||
@obj.collections[key].docs
|
||||
else
|
||||
super(key)
|
||||
end
|
||||
end
|
||||
|
||||
def key?(key)
|
||||
(key != "posts" && @obj.collections.key?(key)) || super
|
||||
end
|
||||
|
||||
def posts
|
||||
@site_posts ||= @obj.posts.docs.sort { |a, b| b <=> a }
|
||||
end
|
||||
|
||||
def html_pages
|
||||
@site_html_pages ||= @obj.pages.select do |page|
|
||||
page.html? || page.url.end_with?("/")
|
||||
end
|
||||
end
|
||||
|
||||
def collections
|
||||
@site_collections ||= @obj.collections.values.sort_by(&:label).map(&:to_liquid)
|
||||
end
|
||||
|
||||
# `Site#documents` cannot be memoized so that `Site#docs_to_write` can access the
|
||||
# latest state of the attribute.
|
||||
#
|
||||
# Since this method will be called after `Site#pre_render` hook, the `Site#documents`
|
||||
# array shouldn't thereafter change and can therefore be safely memoized to prevent
|
||||
# additional computation of `Site#documents`.
|
||||
def documents
|
||||
@documents ||= @obj.documents
|
||||
end
|
||||
|
||||
# `{{ site.related_posts }}` is how posts can get posts related to
|
||||
# them, either through LSI if it's enabled, or through the most
|
||||
# recent posts.
|
||||
# We should remove this in 4.0 and switch to `{{ post.related_posts }}`.
|
||||
def related_posts
|
||||
return nil unless @current_document.is_a?(Jekyll::Document)
|
||||
|
||||
@current_document.related_posts
|
||||
end
|
||||
attr_writer :current_document
|
||||
|
||||
# return nil for `{{ site.config }}` even if --config was passed via CLI
|
||||
def config; end
|
||||
end
|
||||
end
|
||||
end
|
||||
14
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/drops/static_file_drop.rb
vendored
Normal file
14
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/drops/static_file_drop.rb
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Jekyll
|
||||
module Drops
|
||||
class StaticFileDrop < Drop
|
||||
extend Forwardable
|
||||
delegate_methods :name, :extname, :modified_time, :basename
|
||||
delegate_method_as :relative_path, :path
|
||||
delegate_method_as :type, :collection
|
||||
|
||||
private delegate_method_as :data, :fallback_data
|
||||
end
|
||||
end
|
||||
end
|
||||
26
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/drops/unified_payload_drop.rb
vendored
Normal file
26
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/drops/unified_payload_drop.rb
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Jekyll
|
||||
module Drops
|
||||
class UnifiedPayloadDrop < Drop
|
||||
mutable true
|
||||
|
||||
attr_accessor :page, :layout, :content, :paginator
|
||||
attr_accessor :highlighter_prefix, :highlighter_suffix
|
||||
|
||||
def jekyll
|
||||
JekyllDrop.global
|
||||
end
|
||||
|
||||
def site
|
||||
@site_drop ||= SiteDrop.new(@obj)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def fallback_data
|
||||
@fallback_data ||= {}
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
140
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/drops/url_drop.rb
vendored
Normal file
140
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/drops/url_drop.rb
vendored
Normal file
@@ -0,0 +1,140 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Jekyll
|
||||
module Drops
|
||||
class UrlDrop < Drop
|
||||
extend Forwardable
|
||||
|
||||
mutable false
|
||||
|
||||
delegate_method :output_ext
|
||||
delegate_method_as :cleaned_relative_path, :path
|
||||
|
||||
def collection
|
||||
@obj.collection.label
|
||||
end
|
||||
|
||||
def name
|
||||
Utils.slugify(@obj.basename_without_ext)
|
||||
end
|
||||
|
||||
def title
|
||||
Utils.slugify(@obj.data["slug"], :mode => "pretty", :cased => true) ||
|
||||
Utils.slugify(@obj.basename_without_ext, :mode => "pretty", :cased => true)
|
||||
end
|
||||
|
||||
def slug
|
||||
Utils.slugify(@obj.data["slug"]) || Utils.slugify(@obj.basename_without_ext)
|
||||
end
|
||||
|
||||
def categories
|
||||
category_set = Set.new
|
||||
Array(@obj.data["categories"]).each do |category|
|
||||
category_set << category.to_s.downcase
|
||||
end
|
||||
category_set.to_a.join("/")
|
||||
end
|
||||
|
||||
# Similar to output from #categories, but each category will be downcased and
|
||||
# all non-alphanumeric characters of the category replaced with a hyphen.
|
||||
def slugified_categories
|
||||
Array(@obj.data["categories"]).each_with_object(Set.new) do |category, set|
|
||||
set << Utils.slugify(category.to_s)
|
||||
end.to_a.join("/")
|
||||
end
|
||||
|
||||
# CCYY
|
||||
def year
|
||||
@obj.date.strftime("%Y")
|
||||
end
|
||||
|
||||
# MM: 01..12
|
||||
def month
|
||||
@obj.date.strftime("%m")
|
||||
end
|
||||
|
||||
# DD: 01..31
|
||||
def day
|
||||
@obj.date.strftime("%d")
|
||||
end
|
||||
|
||||
# hh: 00..23
|
||||
def hour
|
||||
@obj.date.strftime("%H")
|
||||
end
|
||||
|
||||
# mm: 00..59
|
||||
def minute
|
||||
@obj.date.strftime("%M")
|
||||
end
|
||||
|
||||
# ss: 00..59
|
||||
def second
|
||||
@obj.date.strftime("%S")
|
||||
end
|
||||
|
||||
# D: 1..31
|
||||
def i_day
|
||||
@obj.date.strftime("%-d")
|
||||
end
|
||||
|
||||
# M: 1..12
|
||||
def i_month
|
||||
@obj.date.strftime("%-m")
|
||||
end
|
||||
|
||||
# MMM: Jan..Dec
|
||||
def short_month
|
||||
@obj.date.strftime("%b")
|
||||
end
|
||||
|
||||
# MMMM: January..December
|
||||
def long_month
|
||||
@obj.date.strftime("%B")
|
||||
end
|
||||
|
||||
# YY: 00..99
|
||||
def short_year
|
||||
@obj.date.strftime("%y")
|
||||
end
|
||||
|
||||
# CCYYw, ISO week year
|
||||
# may differ from CCYY for the first days of January and last days of December
|
||||
def w_year
|
||||
@obj.date.strftime("%G")
|
||||
end
|
||||
|
||||
# WW: 01..53
|
||||
# %W and %U do not comply with ISO 8601-1
|
||||
def week
|
||||
@obj.date.strftime("%V")
|
||||
end
|
||||
|
||||
# d: 1..7 (Monday..Sunday)
|
||||
def w_day
|
||||
@obj.date.strftime("%u")
|
||||
end
|
||||
|
||||
# dd: Mon..Sun
|
||||
def short_day
|
||||
@obj.date.strftime("%a")
|
||||
end
|
||||
|
||||
# ddd: Monday..Sunday
|
||||
def long_day
|
||||
@obj.date.strftime("%A")
|
||||
end
|
||||
|
||||
# DDD: 001..366
|
||||
def y_day
|
||||
@obj.date.strftime("%j")
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def fallback_data
|
||||
@fallback_data ||= {}
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
121
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/entry_filter.rb
vendored
Normal file
121
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/entry_filter.rb
vendored
Normal file
@@ -0,0 +1,121 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Jekyll
|
||||
class EntryFilter
|
||||
attr_reader :site
|
||||
|
||||
SPECIAL_LEADING_CHAR_REGEX = %r!\A#{Regexp.union([".", "_", "#", "~"])}!o.freeze
|
||||
|
||||
def initialize(site, base_directory = nil)
|
||||
@site = site
|
||||
@base_directory = derive_base_directory(
|
||||
@site, base_directory.to_s.dup
|
||||
)
|
||||
end
|
||||
|
||||
def base_directory
|
||||
@base_directory.to_s
|
||||
end
|
||||
|
||||
def derive_base_directory(site, base_dir)
|
||||
base_dir[site.source] = "" if base_dir.start_with?(site.source)
|
||||
base_dir
|
||||
end
|
||||
|
||||
def relative_to_source(entry)
|
||||
File.join(
|
||||
base_directory, entry
|
||||
)
|
||||
end
|
||||
|
||||
def filter(entries)
|
||||
entries.reject do |e|
|
||||
# Reject this entry if it is just a "dot" representation.
|
||||
# e.g.: '.', '..', '_movies/.', 'music/..', etc
|
||||
next true if e.end_with?(".")
|
||||
|
||||
# Check if the current entry is explicitly included and cache the result
|
||||
included = included?(e)
|
||||
|
||||
# Reject current entry if it is excluded but not explicitly included as well.
|
||||
next true if excluded?(e) && !included
|
||||
|
||||
# Reject current entry if it is a symlink.
|
||||
next true if symlink?(e)
|
||||
|
||||
# Do not reject current entry if it is explicitly included.
|
||||
next false if included
|
||||
|
||||
# Reject current entry if it is special or a backup file.
|
||||
special?(e) || backup?(e)
|
||||
end
|
||||
end
|
||||
|
||||
def included?(entry)
|
||||
glob_include?(site.include, entry) ||
|
||||
glob_include?(site.include, File.basename(entry))
|
||||
end
|
||||
|
||||
def special?(entry)
|
||||
SPECIAL_LEADING_CHAR_REGEX.match?(entry) ||
|
||||
SPECIAL_LEADING_CHAR_REGEX.match?(File.basename(entry))
|
||||
end
|
||||
|
||||
def backup?(entry)
|
||||
entry.end_with?("~")
|
||||
end
|
||||
|
||||
def excluded?(entry)
|
||||
glob_include?(site.exclude - site.include, relative_to_source(entry)).tap do |excluded|
|
||||
if excluded
|
||||
Jekyll.logger.debug(
|
||||
"EntryFilter:",
|
||||
"excluded #{relative_to_source(entry)}"
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# --
|
||||
# Check if a file is a symlink.
|
||||
# NOTE: This can be converted to allowing even in safe,
|
||||
# since we use Pathutil#in_path? now.
|
||||
# --
|
||||
def symlink?(entry)
|
||||
site.safe && File.symlink?(entry) && symlink_outside_site_source?(entry)
|
||||
end
|
||||
|
||||
# --
|
||||
# NOTE: Pathutil#in_path? gets the realpath.
|
||||
# @param [<Anything>] entry the entry you want to validate.
|
||||
# Check if a path is outside of our given root.
|
||||
# --
|
||||
def symlink_outside_site_source?(entry)
|
||||
!Pathutil.new(entry).in_path?(
|
||||
site.in_source_dir
|
||||
)
|
||||
end
|
||||
|
||||
# Check if an entry matches a specific pattern.
|
||||
# Returns true if path matches against any glob pattern, else false.
|
||||
def glob_include?(enumerator, entry)
|
||||
entry_with_source = PathManager.join(site.source, entry)
|
||||
entry_is_directory = File.directory?(entry_with_source)
|
||||
|
||||
enumerator.any? do |pattern|
|
||||
case pattern
|
||||
when String
|
||||
pattern_with_source = PathManager.join(site.source, pattern)
|
||||
|
||||
File.fnmatch?(pattern_with_source, entry_with_source) ||
|
||||
entry_with_source.start_with?(pattern_with_source) ||
|
||||
(pattern_with_source == "#{entry_with_source}/" if entry_is_directory)
|
||||
when Regexp
|
||||
pattern.match?(entry_with_source)
|
||||
else
|
||||
false
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
20
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/errors.rb
vendored
Normal file
20
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/errors.rb
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Jekyll
|
||||
module Errors
|
||||
FatalException = Class.new(::RuntimeError)
|
||||
|
||||
InvalidThemeName = Class.new(FatalException)
|
||||
|
||||
DropMutationException = Class.new(FatalException)
|
||||
InvalidPermalinkError = Class.new(FatalException)
|
||||
InvalidYAMLFrontMatterError = Class.new(FatalException)
|
||||
MissingDependencyException = Class.new(FatalException)
|
||||
|
||||
InvalidDateError = Class.new(FatalException)
|
||||
InvalidPostNameError = Class.new(FatalException)
|
||||
PostURLError = Class.new(FatalException)
|
||||
InvalidURLError = Class.new(FatalException)
|
||||
InvalidConfigurationError = Class.new(FatalException)
|
||||
end
|
||||
end
|
||||
201
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/excerpt.rb
vendored
Normal file
201
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/excerpt.rb
vendored
Normal file
@@ -0,0 +1,201 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Jekyll
|
||||
class Excerpt
|
||||
extend Forwardable
|
||||
|
||||
attr_accessor :doc
|
||||
attr_accessor :content, :ext
|
||||
attr_writer :output
|
||||
|
||||
def_delegators :@doc,
|
||||
:site, :name, :ext, :extname,
|
||||
:collection, :related_posts, :type,
|
||||
:coffeescript_file?, :yaml_file?,
|
||||
:url, :next_doc, :previous_doc
|
||||
|
||||
private :coffeescript_file?, :yaml_file?
|
||||
|
||||
# Initialize this Excerpt instance.
|
||||
#
|
||||
# doc - The Document.
|
||||
#
|
||||
# Returns the new Excerpt.
|
||||
def initialize(doc)
|
||||
self.doc = doc
|
||||
self.content = extract_excerpt(doc.content)
|
||||
end
|
||||
|
||||
# Fetch YAML front-matter data from related doc, without layout key
|
||||
#
|
||||
# Returns Hash of doc data
|
||||
def data
|
||||
@data ||= doc.data.dup
|
||||
@data.delete("layout")
|
||||
@data.delete("excerpt")
|
||||
@data
|
||||
end
|
||||
|
||||
def trigger_hooks(*); end
|
||||
|
||||
# 'Path' of the excerpt.
|
||||
#
|
||||
# Returns the path for the doc this excerpt belongs to with #excerpt appended
|
||||
def path
|
||||
File.join(doc.path, "#excerpt")
|
||||
end
|
||||
|
||||
# 'Relative Path' of the excerpt.
|
||||
#
|
||||
# Returns the relative_path for the doc this excerpt belongs to with #excerpt appended
|
||||
def relative_path
|
||||
@relative_path ||= File.join(doc.relative_path, "#excerpt")
|
||||
end
|
||||
|
||||
# Check if excerpt includes a string
|
||||
#
|
||||
# Returns true if the string passed in
|
||||
def include?(something)
|
||||
output&.include?(something) || content.include?(something)
|
||||
end
|
||||
|
||||
# The UID for this doc (useful in feeds).
|
||||
# e.g. /2008/11/05/my-awesome-doc
|
||||
#
|
||||
# Returns the String UID.
|
||||
def id
|
||||
"#{doc.id}#excerpt"
|
||||
end
|
||||
|
||||
def to_s
|
||||
output || content
|
||||
end
|
||||
|
||||
def to_liquid
|
||||
Jekyll::Drops::ExcerptDrop.new(self)
|
||||
end
|
||||
|
||||
# Returns the shorthand String identifier of this doc.
|
||||
def inspect
|
||||
"<#{self.class} id=#{id}>"
|
||||
end
|
||||
|
||||
def output
|
||||
@output ||= Renderer.new(doc.site, self, site.site_payload).run
|
||||
end
|
||||
|
||||
def place_in_layout?
|
||||
false
|
||||
end
|
||||
|
||||
def render_with_liquid?
|
||||
return false if data["render_with_liquid"] == false
|
||||
|
||||
!(coffeescript_file? || yaml_file? || !Utils.has_liquid_construct?(content))
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
# Internal: Extract excerpt from the content
|
||||
#
|
||||
# By default excerpt is your first paragraph of a doc: everything before
|
||||
# the first two new lines:
|
||||
#
|
||||
# ---
|
||||
# title: Example
|
||||
# ---
|
||||
#
|
||||
# First paragraph with [link][1].
|
||||
#
|
||||
# Second paragraph.
|
||||
#
|
||||
# [1]: http://example.com/
|
||||
#
|
||||
# This is fairly good option for Markdown and Textile files. But might cause
|
||||
# problems for HTML docs (which is quite unusual for Jekyll). If default
|
||||
# excerpt delimiter is not good for you, you might want to set your own via
|
||||
# configuration option `excerpt_separator`. For example, following is a good
|
||||
# alternative for HTML docs:
|
||||
#
|
||||
# # file: _config.yml
|
||||
# excerpt_separator: "<!-- more -->"
|
||||
#
|
||||
# Notice that all markdown-style link references will be appended to the
|
||||
# excerpt. So the example doc above will have this excerpt source:
|
||||
#
|
||||
# First paragraph with [link][1].
|
||||
#
|
||||
# [1]: http://example.com/
|
||||
#
|
||||
# Excerpts are rendered same time as content is rendered.
|
||||
#
|
||||
# Returns excerpt String
|
||||
|
||||
LIQUID_TAG_REGEX = %r!{%-?\s*(\w+)\s*.*?-?%}!m.freeze
|
||||
MKDWN_LINK_REF_REGEX = %r!^ {0,3}(?:(\[[^\]]+\])(:.+))$!.freeze
|
||||
|
||||
def extract_excerpt(doc_content)
|
||||
head, _, tail = doc_content.to_s.partition(doc.excerpt_separator)
|
||||
return head if tail.empty?
|
||||
|
||||
head = sanctify_liquid_tags(head) if head.include?("{%")
|
||||
definitions = extract_markdown_link_reference_defintions(head, tail)
|
||||
return head if definitions.empty?
|
||||
|
||||
head << "\n\n" << definitions.join("\n")
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# append appropriate closing tag(s) (for each Liquid block), to the `head` if the
|
||||
# partitioning resulted in leaving the closing tag somewhere in the `tail` partition.
|
||||
def sanctify_liquid_tags(head)
|
||||
modified = false
|
||||
tag_names = head.scan(LIQUID_TAG_REGEX)
|
||||
tag_names.flatten!
|
||||
tag_names.reverse_each do |tag_name|
|
||||
next unless liquid_block?(tag_name)
|
||||
next if endtag_regex_stash(tag_name).match?(head)
|
||||
|
||||
modified = true
|
||||
head << "\n{% end#{tag_name} %}"
|
||||
end
|
||||
|
||||
print_build_warning if modified
|
||||
head
|
||||
end
|
||||
|
||||
def extract_markdown_link_reference_defintions(head, tail)
|
||||
[].tap do |definitions|
|
||||
tail.scan(MKDWN_LINK_REF_REGEX).each do |segments|
|
||||
definitions << segments.join if head.include?(segments[0])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def endtag_regex_stash(tag_name)
|
||||
@endtag_regex_stash ||= {}
|
||||
@endtag_regex_stash[tag_name] ||= %r!{%-?\s*end#{tag_name}.*?\s*-?%}!m
|
||||
end
|
||||
|
||||
def liquid_block?(tag_name)
|
||||
return false unless tag_name.is_a?(String)
|
||||
return false unless Liquid::Template.tags[tag_name]
|
||||
|
||||
Liquid::Template.tags[tag_name].ancestors.include?(Liquid::Block)
|
||||
rescue NoMethodError
|
||||
Jekyll.logger.error "Error:",
|
||||
"A Liquid tag in the excerpt of #{doc.relative_path} couldn't be parsed."
|
||||
raise
|
||||
end
|
||||
|
||||
def print_build_warning
|
||||
Jekyll.logger.warn "Warning:", "Excerpt modified in #{doc.relative_path}!"
|
||||
Jekyll.logger.warn "", "Found a Liquid block containing the excerpt separator" \
|
||||
" #{doc.excerpt_separator.inspect}. "
|
||||
Jekyll.logger.warn "", "The block has been modified with the appropriate closing tag."
|
||||
Jekyll.logger.warn "", "Feel free to define a custom excerpt or excerpt_separator in the"
|
||||
Jekyll.logger.warn "", "document's Front Matter if the generated excerpt is unsatisfactory."
|
||||
end
|
||||
end
|
||||
end
|
||||
79
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/external.rb
vendored
Normal file
79
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/external.rb
vendored
Normal file
@@ -0,0 +1,79 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Jekyll
|
||||
module External
|
||||
class << self
|
||||
#
|
||||
# Gems that, if installed, should be loaded.
|
||||
# Usually contain subcommands.
|
||||
#
|
||||
def blessed_gems
|
||||
%w(
|
||||
jekyll-compose
|
||||
jekyll-docs
|
||||
jekyll-import
|
||||
)
|
||||
end
|
||||
|
||||
#
|
||||
# Require a gem or file if it's present, otherwise silently fail.
|
||||
#
|
||||
# names - a string gem name or array of gem names
|
||||
#
|
||||
def require_if_present(names)
|
||||
Array(names).each do |name|
|
||||
begin
|
||||
require name
|
||||
rescue LoadError
|
||||
Jekyll.logger.debug "Couldn't load #{name}. Skipping."
|
||||
yield(name, version_constraint(name)) if block_given?
|
||||
false
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
# The version constraint required to activate a given gem.
|
||||
# Usually the gem version requirement is "> 0," because any version
|
||||
# will do. In the case of jekyll-docs, however, we require the exact
|
||||
# same version as Jekyll.
|
||||
#
|
||||
# Returns a String version constraint in a parseable form for
|
||||
# RubyGems.
|
||||
def version_constraint(gem_name)
|
||||
return "= #{Jekyll::VERSION}" if gem_name.to_s.eql?("jekyll-docs")
|
||||
|
||||
"> 0"
|
||||
end
|
||||
|
||||
#
|
||||
# Require a gem or gems. If it's not present, show a very nice error
|
||||
# message that explains everything and is much more helpful than the
|
||||
# normal LoadError.
|
||||
#
|
||||
# names - a string gem name or array of gem names
|
||||
#
|
||||
def require_with_graceful_fail(names)
|
||||
Array(names).each do |name|
|
||||
begin
|
||||
Jekyll.logger.debug "Requiring:", name.to_s
|
||||
require name
|
||||
rescue LoadError => e
|
||||
Jekyll.logger.error "Dependency Error:", <<~MSG
|
||||
Yikes! It looks like you don't have #{name} or one of its dependencies installed.
|
||||
In order to use Jekyll as currently configured, you'll need to install this gem.
|
||||
|
||||
If you've run Jekyll with `bundle exec`, ensure that you have included the #{name}
|
||||
gem in your Gemfile as well.
|
||||
|
||||
The full error message from Ruby is: '#{e.message}'
|
||||
|
||||
If you run into trouble, you can find helpful resources at https://jekyllrb.com/help/!
|
||||
MSG
|
||||
raise Jekyll::Errors::MissingDependencyException, name
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
535
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/filters.rb
vendored
Normal file
535
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/filters.rb
vendored
Normal file
@@ -0,0 +1,535 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require_all "jekyll/filters"
|
||||
|
||||
module Jekyll
|
||||
module Filters
|
||||
include URLFilters
|
||||
include GroupingFilters
|
||||
include DateFilters
|
||||
|
||||
# Convert a Markdown string into HTML output.
|
||||
#
|
||||
# input - The Markdown String to convert.
|
||||
#
|
||||
# Returns the HTML formatted String.
|
||||
def markdownify(input)
|
||||
@context.registers[:site].find_converter_instance(
|
||||
Jekyll::Converters::Markdown
|
||||
).convert(input.to_s)
|
||||
end
|
||||
|
||||
# Convert quotes into smart quotes.
|
||||
#
|
||||
# input - The String to convert.
|
||||
#
|
||||
# Returns the smart-quotified String.
|
||||
def smartify(input)
|
||||
@context.registers[:site].find_converter_instance(
|
||||
Jekyll::Converters::SmartyPants
|
||||
).convert(input.to_s)
|
||||
end
|
||||
|
||||
# Convert a Sass string into CSS output.
|
||||
#
|
||||
# input - The Sass String to convert.
|
||||
#
|
||||
# Returns the CSS formatted String.
|
||||
def sassify(input)
|
||||
@context.registers[:site].find_converter_instance(
|
||||
Jekyll::Converters::Sass
|
||||
).convert(input)
|
||||
end
|
||||
|
||||
# Convert a Scss string into CSS output.
|
||||
#
|
||||
# input - The Scss String to convert.
|
||||
#
|
||||
# Returns the CSS formatted String.
|
||||
def scssify(input)
|
||||
@context.registers[:site].find_converter_instance(
|
||||
Jekyll::Converters::Scss
|
||||
).convert(input)
|
||||
end
|
||||
|
||||
# Slugify a filename or title.
|
||||
#
|
||||
# input - The filename or title to slugify.
|
||||
# mode - how string is slugified
|
||||
#
|
||||
# Returns the given filename or title as a lowercase URL String.
|
||||
# See Utils.slugify for more detail.
|
||||
def slugify(input, mode = nil)
|
||||
Utils.slugify(input, :mode => mode)
|
||||
end
|
||||
|
||||
# XML escape a string for use. Replaces any special characters with
|
||||
# appropriate HTML entity replacements.
|
||||
#
|
||||
# input - The String to escape.
|
||||
#
|
||||
# Examples
|
||||
#
|
||||
# xml_escape('foo "bar" <baz>')
|
||||
# # => "foo "bar" <baz>"
|
||||
#
|
||||
# Returns the escaped String.
|
||||
def xml_escape(input)
|
||||
input.to_s.encode(:xml => :attr).gsub(%r!\A"|"\Z!, "")
|
||||
end
|
||||
|
||||
# CGI escape a string for use in a URL. Replaces any special characters
|
||||
# with appropriate %XX replacements.
|
||||
#
|
||||
# input - The String to escape.
|
||||
#
|
||||
# Examples
|
||||
#
|
||||
# cgi_escape('foo,bar;baz?')
|
||||
# # => "foo%2Cbar%3Bbaz%3F"
|
||||
#
|
||||
# Returns the escaped String.
|
||||
def cgi_escape(input)
|
||||
CGI.escape(input)
|
||||
end
|
||||
|
||||
# URI escape a string.
|
||||
#
|
||||
# input - The String to escape.
|
||||
#
|
||||
# Examples
|
||||
#
|
||||
# uri_escape('foo, bar \\baz?')
|
||||
# # => "foo,%20bar%20%5Cbaz?"
|
||||
#
|
||||
# Returns the escaped String.
|
||||
def uri_escape(input)
|
||||
Addressable::URI.normalize_component(input)
|
||||
end
|
||||
|
||||
# Replace any whitespace in the input string with a single space
|
||||
#
|
||||
# input - The String on which to operate.
|
||||
#
|
||||
# Returns the formatted String
|
||||
def normalize_whitespace(input)
|
||||
input.to_s.gsub(%r!\s+!, " ").tap(&:strip!)
|
||||
end
|
||||
|
||||
# Count the number of words in the input string.
|
||||
#
|
||||
# input - The String on which to operate.
|
||||
#
|
||||
# Returns the Integer word count.
|
||||
def number_of_words(input, mode = nil)
|
||||
cjk_charset = '\p{Han}\p{Katakana}\p{Hiragana}\p{Hangul}'
|
||||
cjk_regex = %r![#{cjk_charset}]!o
|
||||
word_regex = %r![^#{cjk_charset}\s]+!o
|
||||
|
||||
case mode
|
||||
when "cjk"
|
||||
input.scan(cjk_regex).length + input.scan(word_regex).length
|
||||
when "auto"
|
||||
cjk_count = input.scan(cjk_regex).length
|
||||
cjk_count.zero? ? input.split.length : cjk_count + input.scan(word_regex).length
|
||||
else
|
||||
input.split.length
|
||||
end
|
||||
end
|
||||
|
||||
# Join an array of things into a string by separating with commas and the
|
||||
# word "and" for the last one.
|
||||
#
|
||||
# array - The Array of Strings to join.
|
||||
# connector - Word used to connect the last 2 items in the array
|
||||
#
|
||||
# Examples
|
||||
#
|
||||
# array_to_sentence_string(["apples", "oranges", "grapes"])
|
||||
# # => "apples, oranges, and grapes"
|
||||
#
|
||||
# Returns the formatted String.
|
||||
def array_to_sentence_string(array, connector = "and")
|
||||
case array.length
|
||||
when 0
|
||||
""
|
||||
when 1
|
||||
array[0].to_s
|
||||
when 2
|
||||
"#{array[0]} #{connector} #{array[1]}"
|
||||
else
|
||||
"#{array[0...-1].join(", ")}, #{connector} #{array[-1]}"
|
||||
end
|
||||
end
|
||||
|
||||
# Convert the input into json string
|
||||
#
|
||||
# input - The Array or Hash to be converted
|
||||
#
|
||||
# Returns the converted json string
|
||||
def jsonify(input)
|
||||
as_liquid(input).to_json
|
||||
end
|
||||
|
||||
# Filter an array of objects
|
||||
#
|
||||
# input - the object array.
|
||||
# property - the property within each object to filter by.
|
||||
# value - the desired value.
|
||||
# Cannot be an instance of Array nor Hash since calling #to_s on them returns
|
||||
# their `#inspect` string object.
|
||||
#
|
||||
# Returns the filtered array of objects
|
||||
def where(input, property, value)
|
||||
return input if !property || value.is_a?(Array) || value.is_a?(Hash)
|
||||
return input unless input.respond_to?(:select)
|
||||
|
||||
input = input.values if input.is_a?(Hash)
|
||||
input_id = input.hash
|
||||
|
||||
# implement a hash based on method parameters to cache the end-result
|
||||
# for given parameters.
|
||||
@where_filter_cache ||= {}
|
||||
@where_filter_cache[input_id] ||= {}
|
||||
@where_filter_cache[input_id][property] ||= {}
|
||||
|
||||
# stash or retrive results to return
|
||||
@where_filter_cache[input_id][property][value] ||= begin
|
||||
input.select do |object|
|
||||
compare_property_vs_target(item_property(object, property), value)
|
||||
end.to_a
|
||||
end
|
||||
end
|
||||
|
||||
# Filters an array of objects against an expression
|
||||
#
|
||||
# input - the object array
|
||||
# variable - the variable to assign each item to in the expression
|
||||
# expression - a Liquid comparison expression passed in as a string
|
||||
#
|
||||
# Returns the filtered array of objects
|
||||
def where_exp(input, variable, expression)
|
||||
return input unless input.respond_to?(:select)
|
||||
|
||||
input = input.values if input.is_a?(Hash) # FIXME
|
||||
|
||||
condition = parse_condition(expression)
|
||||
@context.stack do
|
||||
input.select do |object|
|
||||
@context[variable] = object
|
||||
condition.evaluate(@context)
|
||||
end
|
||||
end || []
|
||||
end
|
||||
|
||||
# Search an array of objects and returns the first object that has the queried attribute
|
||||
# with the given value or returns nil otherwise.
|
||||
#
|
||||
# input - the object array.
|
||||
# property - the property within each object to search by.
|
||||
# value - the desired value.
|
||||
# Cannot be an instance of Array nor Hash since calling #to_s on them returns
|
||||
# their `#inspect` string object.
|
||||
#
|
||||
# Returns the found object or nil
|
||||
#
|
||||
# rubocop:disable Metrics/CyclomaticComplexity
|
||||
def find(input, property, value)
|
||||
return input if !property || value.is_a?(Array) || value.is_a?(Hash)
|
||||
return input unless input.respond_to?(:find)
|
||||
|
||||
input = input.values if input.is_a?(Hash)
|
||||
input_id = input.hash
|
||||
|
||||
# implement a hash based on method parameters to cache the end-result for given parameters.
|
||||
@find_filter_cache ||= {}
|
||||
@find_filter_cache[input_id] ||= {}
|
||||
@find_filter_cache[input_id][property] ||= {}
|
||||
|
||||
# stash or retrive results to return
|
||||
# Since `enum.find` can return nil or false, we use a placeholder string "<__NO MATCH__>"
|
||||
# to validate caching.
|
||||
result = @find_filter_cache[input_id][property][value] ||= begin
|
||||
input.find do |object|
|
||||
compare_property_vs_target(item_property(object, property), value)
|
||||
end || "<__NO MATCH__>"
|
||||
end
|
||||
return nil if result == "<__NO MATCH__>"
|
||||
|
||||
result
|
||||
end
|
||||
# rubocop:enable Metrics/CyclomaticComplexity
|
||||
|
||||
# Searches an array of objects against an expression and returns the first object for which
|
||||
# the expression evaluates to true, or returns nil otherwise.
|
||||
#
|
||||
# input - the object array
|
||||
# variable - the variable to assign each item to in the expression
|
||||
# expression - a Liquid comparison expression passed in as a string
|
||||
#
|
||||
# Returns the found object or nil
|
||||
def find_exp(input, variable, expression)
|
||||
return input unless input.respond_to?(:find)
|
||||
|
||||
input = input.values if input.is_a?(Hash)
|
||||
|
||||
condition = parse_condition(expression)
|
||||
@context.stack do
|
||||
input.find do |object|
|
||||
@context[variable] = object
|
||||
condition.evaluate(@context)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Convert the input into integer
|
||||
#
|
||||
# input - the object string
|
||||
#
|
||||
# Returns the integer value
|
||||
def to_integer(input)
|
||||
return 1 if input == true
|
||||
return 0 if input == false
|
||||
|
||||
input.to_i
|
||||
end
|
||||
|
||||
# Sort an array of objects
|
||||
#
|
||||
# input - the object array
|
||||
# property - property within each object to filter by
|
||||
# nils ('first' | 'last') - nils appear before or after non-nil values
|
||||
#
|
||||
# Returns the filtered array of objects
|
||||
def sort(input, property = nil, nils = "first")
|
||||
raise ArgumentError, "Cannot sort a null object." if input.nil?
|
||||
|
||||
if property.nil?
|
||||
input.sort
|
||||
else
|
||||
case nils
|
||||
when "first"
|
||||
order = - 1
|
||||
when "last"
|
||||
order = + 1
|
||||
else
|
||||
raise ArgumentError, "Invalid nils order: " \
|
||||
"'#{nils}' is not a valid nils order. It must be 'first' or 'last'."
|
||||
end
|
||||
|
||||
sort_input(input, property, order)
|
||||
end
|
||||
end
|
||||
|
||||
def pop(array, num = 1)
|
||||
return array unless array.is_a?(Array)
|
||||
|
||||
num = Liquid::Utils.to_integer(num)
|
||||
new_ary = array.dup
|
||||
new_ary.pop(num)
|
||||
new_ary
|
||||
end
|
||||
|
||||
def push(array, input)
|
||||
return array unless array.is_a?(Array)
|
||||
|
||||
new_ary = array.dup
|
||||
new_ary.push(input)
|
||||
new_ary
|
||||
end
|
||||
|
||||
def shift(array, num = 1)
|
||||
return array unless array.is_a?(Array)
|
||||
|
||||
num = Liquid::Utils.to_integer(num)
|
||||
new_ary = array.dup
|
||||
new_ary.shift(num)
|
||||
new_ary
|
||||
end
|
||||
|
||||
def unshift(array, input)
|
||||
return array unless array.is_a?(Array)
|
||||
|
||||
new_ary = array.dup
|
||||
new_ary.unshift(input)
|
||||
new_ary
|
||||
end
|
||||
|
||||
def sample(input, num = 1)
|
||||
return input unless input.respond_to?(:sample)
|
||||
|
||||
num = Liquid::Utils.to_integer(num) rescue 1
|
||||
if num == 1
|
||||
input.sample
|
||||
else
|
||||
input.sample(num)
|
||||
end
|
||||
end
|
||||
|
||||
# Convert an object into its String representation for debugging
|
||||
#
|
||||
# input - The Object to be converted
|
||||
#
|
||||
# Returns a String representation of the object.
|
||||
def inspect(input)
|
||||
xml_escape(input.inspect)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# Sort the input Enumerable by the given property.
|
||||
# If the property doesn't exist, return the sort order respective of
|
||||
# which item doesn't have the property.
|
||||
# We also utilize the Schwartzian transform to make this more efficient.
|
||||
def sort_input(input, property, order)
|
||||
input.map { |item| [item_property(item, property), item] }
|
||||
.sort! do |a_info, b_info|
|
||||
a_property = a_info.first
|
||||
b_property = b_info.first
|
||||
|
||||
if !a_property.nil? && b_property.nil?
|
||||
- order
|
||||
elsif a_property.nil? && !b_property.nil?
|
||||
+ order
|
||||
else
|
||||
a_property <=> b_property || a_property.to_s <=> b_property.to_s
|
||||
end
|
||||
end
|
||||
.map!(&:last)
|
||||
end
|
||||
|
||||
# `where` filter helper
|
||||
#
|
||||
def compare_property_vs_target(property, target)
|
||||
case target
|
||||
when NilClass
|
||||
return true if property.nil?
|
||||
when Liquid::Expression::MethodLiteral # `empty` or `blank`
|
||||
target = target.to_s
|
||||
return true if property == target || Array(property).join == target
|
||||
else
|
||||
target = target.to_s
|
||||
if property.is_a? String
|
||||
return true if property == target
|
||||
else
|
||||
Array(property).each do |prop|
|
||||
return true if prop.to_s == target
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
false
|
||||
end
|
||||
|
||||
def item_property(item, property)
|
||||
@item_property_cache ||= @context.registers[:site].filter_cache[:item_property] ||= {}
|
||||
@item_property_cache[property] ||= {}
|
||||
@item_property_cache[property][item] ||= begin
|
||||
property = property.to_s
|
||||
property = if item.respond_to?(:to_liquid)
|
||||
read_liquid_attribute(item.to_liquid, property)
|
||||
elsif item.respond_to?(:data)
|
||||
item.data[property]
|
||||
else
|
||||
item[property]
|
||||
end
|
||||
|
||||
parse_sort_input(property)
|
||||
end
|
||||
end
|
||||
|
||||
def read_liquid_attribute(liquid_data, property)
|
||||
return liquid_data[property] unless property.include?(".")
|
||||
|
||||
property.split(".").reduce(liquid_data) do |data, key|
|
||||
data.respond_to?(:[]) && data[key]
|
||||
end
|
||||
end
|
||||
|
||||
FLOAT_LIKE = %r!\A\s*-?(?:\d+\.?\d*|\.\d+)\s*\Z!.freeze
|
||||
INTEGER_LIKE = %r!\A\s*-?\d+\s*\Z!.freeze
|
||||
private_constant :FLOAT_LIKE, :INTEGER_LIKE
|
||||
|
||||
# return numeric values as numbers for proper sorting
|
||||
def parse_sort_input(property)
|
||||
stringified = property.to_s
|
||||
return property.to_i if INTEGER_LIKE.match?(stringified)
|
||||
return property.to_f if FLOAT_LIKE.match?(stringified)
|
||||
|
||||
property
|
||||
end
|
||||
|
||||
def as_liquid(item)
|
||||
case item
|
||||
when Hash
|
||||
item.each_with_object({}) { |(k, v), result| result[as_liquid(k)] = as_liquid(v) }
|
||||
when Array
|
||||
item.map { |i| as_liquid(i) }
|
||||
else
|
||||
if item.respond_to?(:to_liquid)
|
||||
liquidated = item.to_liquid
|
||||
# prevent infinite recursion for simple types (which return `self`)
|
||||
if liquidated == item
|
||||
item
|
||||
else
|
||||
as_liquid(liquidated)
|
||||
end
|
||||
else
|
||||
item
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# ----------- The following set of code was *adapted* from Liquid::If
|
||||
# ----------- ref: https://git.io/vp6K6
|
||||
|
||||
# Parse a string to a Liquid Condition
|
||||
def parse_condition(exp)
|
||||
parser = Liquid::Parser.new(exp)
|
||||
condition = parse_binary_comparison(parser)
|
||||
|
||||
parser.consume(:end_of_string)
|
||||
condition
|
||||
end
|
||||
|
||||
# Generate a Liquid::Condition object from a Liquid::Parser object additionally processing
|
||||
# the parsed expression based on whether the expression consists of binary operations with
|
||||
# Liquid operators `and` or `or`
|
||||
#
|
||||
# - parser: an instance of Liquid::Parser
|
||||
#
|
||||
# Returns an instance of Liquid::Condition
|
||||
def parse_binary_comparison(parser)
|
||||
condition = parse_comparison(parser)
|
||||
first_condition = condition
|
||||
while (binary_operator = parser.id?("and") || parser.id?("or"))
|
||||
child_condition = parse_comparison(parser)
|
||||
condition.send(binary_operator, child_condition)
|
||||
condition = child_condition
|
||||
end
|
||||
first_condition
|
||||
end
|
||||
|
||||
# Generates a Liquid::Condition object from a Liquid::Parser object based on whether the parsed
|
||||
# expression involves a "comparison" operator (e.g. <, ==, >, !=, etc)
|
||||
#
|
||||
# - parser: an instance of Liquid::Parser
|
||||
#
|
||||
# Returns an instance of Liquid::Condition
|
||||
def parse_comparison(parser)
|
||||
left_operand = Liquid::Expression.parse(parser.expression)
|
||||
operator = parser.consume?(:comparison)
|
||||
|
||||
# No comparison-operator detected. Initialize a Liquid::Condition using only left operand
|
||||
return Liquid::Condition.new(left_operand) unless operator
|
||||
|
||||
# Parse what remained after extracting the left operand and the `:comparison` operator
|
||||
# and initialize a Liquid::Condition object using the operands and the comparison-operator
|
||||
Liquid::Condition.new(left_operand, operator, Liquid::Expression.parse(parser.expression))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Liquid::Template.register_filter(
|
||||
Jekyll::Filters
|
||||
)
|
||||
110
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/filters/date_filters.rb
vendored
Normal file
110
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/filters/date_filters.rb
vendored
Normal file
@@ -0,0 +1,110 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Jekyll
|
||||
module Filters
|
||||
module DateFilters
|
||||
# Format a date in short format e.g. "27 Jan 2011".
|
||||
# Ordinal format is also supported, in both the UK
|
||||
# (e.g. "27th Jan 2011") and US ("e.g. Jan 27th, 2011") formats.
|
||||
# UK format is the default.
|
||||
#
|
||||
# date - the Time to format.
|
||||
# type - if "ordinal" the returned String will be in ordinal format
|
||||
# style - if "US" the returned String will be in US format.
|
||||
# Otherwise it will be in UK format.
|
||||
#
|
||||
# Returns the formatting String.
|
||||
def date_to_string(date, type = nil, style = nil)
|
||||
stringify_date(date, "%b", type, style)
|
||||
end
|
||||
|
||||
# Format a date in long format e.g. "27 January 2011".
|
||||
# Ordinal format is also supported, in both the UK
|
||||
# (e.g. "27th January 2011") and US ("e.g. January 27th, 2011") formats.
|
||||
# UK format is the default.
|
||||
#
|
||||
# date - the Time to format.
|
||||
# type - if "ordinal" the returned String will be in ordinal format
|
||||
# style - if "US" the returned String will be in US format.
|
||||
# Otherwise it will be in UK format.
|
||||
#
|
||||
# Returns the formatted String.
|
||||
def date_to_long_string(date, type = nil, style = nil)
|
||||
stringify_date(date, "%B", type, style)
|
||||
end
|
||||
|
||||
# Format a date for use in XML.
|
||||
#
|
||||
# date - The Time to format.
|
||||
#
|
||||
# Examples
|
||||
#
|
||||
# date_to_xmlschema(Time.now)
|
||||
# # => "2011-04-24T20:34:46+08:00"
|
||||
#
|
||||
# Returns the formatted String.
|
||||
def date_to_xmlschema(date)
|
||||
return date if date.to_s.empty?
|
||||
|
||||
time(date).xmlschema
|
||||
end
|
||||
|
||||
# Format a date according to RFC-822
|
||||
#
|
||||
# date - The Time to format.
|
||||
#
|
||||
# Examples
|
||||
#
|
||||
# date_to_rfc822(Time.now)
|
||||
# # => "Sun, 24 Apr 2011 12:34:46 +0000"
|
||||
#
|
||||
# Returns the formatted String.
|
||||
def date_to_rfc822(date)
|
||||
return date if date.to_s.empty?
|
||||
|
||||
time(date).rfc822
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# month_type: Notations that evaluate to 'Month' via `Time#strftime` ("%b", "%B")
|
||||
# type: nil (default) or "ordinal"
|
||||
# style: nil (default) or "US"
|
||||
#
|
||||
# Returns a stringified date or the empty input.
|
||||
def stringify_date(date, month_type, type = nil, style = nil)
|
||||
return date if date.to_s.empty?
|
||||
|
||||
time = time(date)
|
||||
if type == "ordinal"
|
||||
day = time.day
|
||||
ordinal_day = "#{day}#{ordinal(day)}"
|
||||
return time.strftime("#{month_type} #{ordinal_day}, %Y") if style == "US"
|
||||
|
||||
return time.strftime("#{ordinal_day} #{month_type} %Y")
|
||||
end
|
||||
time.strftime("%d #{month_type} %Y")
|
||||
end
|
||||
|
||||
def ordinal(number)
|
||||
return "th" if (11..13).cover?(number)
|
||||
|
||||
case number % 10
|
||||
when 1 then "st"
|
||||
when 2 then "nd"
|
||||
when 3 then "rd"
|
||||
else "th"
|
||||
end
|
||||
end
|
||||
|
||||
def time(input)
|
||||
date = Liquid::Utils.to_date(input)
|
||||
unless date.respond_to?(:to_time)
|
||||
raise Errors::InvalidDateError,
|
||||
"Invalid Date: '#{input.inspect}' is not a valid datetime."
|
||||
end
|
||||
date.to_time.dup.localtime
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
64
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/filters/grouping_filters.rb
vendored
Normal file
64
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/filters/grouping_filters.rb
vendored
Normal file
@@ -0,0 +1,64 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Jekyll
|
||||
module Filters
|
||||
module GroupingFilters
|
||||
# Group an array of items by a property
|
||||
#
|
||||
# input - the inputted Enumerable
|
||||
# property - the property
|
||||
#
|
||||
# Returns an array of Hashes, each looking something like this:
|
||||
# {"name" => "larry"
|
||||
# "items" => [...] } # all the items where `property` == "larry"
|
||||
def group_by(input, property)
|
||||
if groupable?(input)
|
||||
groups = input.group_by { |item| item_property(item, property).to_s }
|
||||
grouped_array(groups)
|
||||
else
|
||||
input
|
||||
end
|
||||
end
|
||||
|
||||
# Group an array of items by an expression
|
||||
#
|
||||
# input - the object array
|
||||
# variable - the variable to assign each item to in the expression
|
||||
# expression -a Liquid comparison expression passed in as a string
|
||||
#
|
||||
# Returns the filtered array of objects
|
||||
def group_by_exp(input, variable, expression)
|
||||
return input unless groupable?(input)
|
||||
|
||||
parsed_expr = parse_expression(expression)
|
||||
@context.stack do
|
||||
groups = input.group_by do |item|
|
||||
@context[variable] = item
|
||||
parsed_expr.render(@context)
|
||||
end
|
||||
grouped_array(groups)
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def parse_expression(str)
|
||||
Liquid::Variable.new(str, Liquid::ParseContext.new)
|
||||
end
|
||||
|
||||
def groupable?(element)
|
||||
element.respond_to?(:group_by)
|
||||
end
|
||||
|
||||
def grouped_array(groups)
|
||||
groups.each_with_object([]) do |item, array|
|
||||
array << {
|
||||
"name" => item.first,
|
||||
"items" => item.last,
|
||||
"size" => item.last.size,
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
98
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/filters/url_filters.rb
vendored
Normal file
98
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/filters/url_filters.rb
vendored
Normal file
@@ -0,0 +1,98 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Jekyll
|
||||
module Filters
|
||||
module URLFilters
|
||||
# Produces an absolute URL based on site.url and site.baseurl.
|
||||
#
|
||||
# input - the URL to make absolute.
|
||||
#
|
||||
# Returns the absolute URL as a String.
|
||||
def absolute_url(input)
|
||||
return if input.nil?
|
||||
|
||||
cache = if input.is_a?(String)
|
||||
(@context.registers[:site].filter_cache[:absolute_url] ||= {})
|
||||
else
|
||||
(@context.registers[:cached_absolute_url] ||= {})
|
||||
end
|
||||
cache[input] ||= compute_absolute_url(input)
|
||||
|
||||
# Duplicate cached string so that the cached value is never mutated by
|
||||
# a subsequent filter.
|
||||
cache[input].dup
|
||||
end
|
||||
|
||||
# Produces a URL relative to the domain root based on site.baseurl
|
||||
# unless it is already an absolute url with an authority (host).
|
||||
#
|
||||
# input - the URL to make relative to the domain root
|
||||
#
|
||||
# Returns a URL relative to the domain root as a String.
|
||||
def relative_url(input)
|
||||
return if input.nil?
|
||||
|
||||
cache = if input.is_a?(String)
|
||||
(@context.registers[:site].filter_cache[:relative_url] ||= {})
|
||||
else
|
||||
(@context.registers[:cached_relative_url] ||= {})
|
||||
end
|
||||
cache[input] ||= compute_relative_url(input)
|
||||
|
||||
# Duplicate cached string so that the cached value is never mutated by
|
||||
# a subsequent filter.
|
||||
cache[input].dup
|
||||
end
|
||||
|
||||
# Strips trailing `/index.html` from URLs to create pretty permalinks
|
||||
#
|
||||
# input - the URL with a possible `/index.html`
|
||||
#
|
||||
# Returns a URL with the trailing `/index.html` removed
|
||||
def strip_index(input)
|
||||
return if input.nil? || input.to_s.empty?
|
||||
|
||||
input.sub(%r!/index\.html?$!, "/")
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def compute_absolute_url(input)
|
||||
input = input.url if input.respond_to?(:url)
|
||||
return input if Addressable::URI.parse(input.to_s).absolute?
|
||||
|
||||
site = @context.registers[:site]
|
||||
site_url = site.config["url"]
|
||||
return relative_url(input) if site_url.nil? || site_url == ""
|
||||
|
||||
Addressable::URI.parse(
|
||||
site_url.to_s + relative_url(input)
|
||||
).normalize.to_s
|
||||
end
|
||||
|
||||
def compute_relative_url(input)
|
||||
input = input.url if input.respond_to?(:url)
|
||||
return input if Addressable::URI.parse(input.to_s).absolute?
|
||||
|
||||
parts = [sanitized_baseurl, input]
|
||||
Addressable::URI.parse(
|
||||
parts.map! { |part| ensure_leading_slash(part.to_s) }.join
|
||||
).normalize.to_s
|
||||
end
|
||||
|
||||
def sanitized_baseurl
|
||||
site = @context.registers[:site]
|
||||
baseurl = site.config["baseurl"]
|
||||
return "" if baseurl.nil?
|
||||
|
||||
baseurl.to_s.chomp("/")
|
||||
end
|
||||
|
||||
def ensure_leading_slash(input)
|
||||
return input if input.nil? || input.empty? || input.start_with?("/")
|
||||
|
||||
"/#{input}"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
240
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/frontmatter_defaults.rb
vendored
Normal file
240
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/frontmatter_defaults.rb
vendored
Normal file
@@ -0,0 +1,240 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Jekyll
|
||||
# This class handles custom defaults for YAML frontmatter settings.
|
||||
# These are set in _config.yml and apply both to internal use (e.g. layout)
|
||||
# and the data available to liquid.
|
||||
#
|
||||
# It is exposed via the frontmatter_defaults method on the site class.
|
||||
class FrontmatterDefaults
|
||||
# Initializes a new instance.
|
||||
def initialize(site)
|
||||
@site = site
|
||||
end
|
||||
|
||||
def reset
|
||||
@glob_cache = {} if @glob_cache
|
||||
end
|
||||
|
||||
def update_deprecated_types(set)
|
||||
return set unless set.key?("scope") && set["scope"].key?("type")
|
||||
|
||||
set["scope"]["type"] =
|
||||
case set["scope"]["type"]
|
||||
when "page"
|
||||
Deprecator.defaults_deprecate_type("page", "pages")
|
||||
"pages"
|
||||
when "post"
|
||||
Deprecator.defaults_deprecate_type("post", "posts")
|
||||
"posts"
|
||||
when "draft"
|
||||
Deprecator.defaults_deprecate_type("draft", "drafts")
|
||||
"drafts"
|
||||
else
|
||||
set["scope"]["type"]
|
||||
end
|
||||
|
||||
set
|
||||
end
|
||||
|
||||
def ensure_time!(set)
|
||||
return set unless set.key?("values") && set["values"].key?("date")
|
||||
return set if set["values"]["date"].is_a?(Time)
|
||||
|
||||
set["values"]["date"] = Utils.parse_date(
|
||||
set["values"]["date"],
|
||||
"An invalid date format was found in a front-matter default set: #{set}"
|
||||
)
|
||||
set
|
||||
end
|
||||
|
||||
# Finds a default value for a given setting, filtered by path and type
|
||||
#
|
||||
# path - the path (relative to the source) of the page,
|
||||
# post or :draft the default is used in
|
||||
# type - a symbol indicating whether a :page,
|
||||
# a :post or a :draft calls this method
|
||||
#
|
||||
# Returns the default value or nil if none was found
|
||||
def find(path, type, setting)
|
||||
value = nil
|
||||
old_scope = nil
|
||||
|
||||
matching_sets(path, type).each do |set|
|
||||
if set["values"].key?(setting) && has_precedence?(old_scope, set["scope"])
|
||||
value = set["values"][setting]
|
||||
old_scope = set["scope"]
|
||||
end
|
||||
end
|
||||
value
|
||||
end
|
||||
|
||||
# Collects a hash with all default values for a page or post
|
||||
#
|
||||
# path - the relative path of the page or post
|
||||
# type - a symbol indicating the type (:post, :page or :draft)
|
||||
#
|
||||
# Returns a hash with all default values (an empty hash if there are none)
|
||||
def all(path, type)
|
||||
defaults = {}
|
||||
old_scope = nil
|
||||
matching_sets(path, type).each do |set|
|
||||
if has_precedence?(old_scope, set["scope"])
|
||||
defaults = Utils.deep_merge_hashes(defaults, set["values"])
|
||||
old_scope = set["scope"]
|
||||
else
|
||||
defaults = Utils.deep_merge_hashes(set["values"], defaults)
|
||||
end
|
||||
end
|
||||
defaults
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# Checks if a given default setting scope matches the given path and type
|
||||
#
|
||||
# scope - the hash indicating the scope, as defined in _config.yml
|
||||
# path - the path to check for
|
||||
# type - the type (:post, :page or :draft) to check for
|
||||
#
|
||||
# Returns true if the scope applies to the given type and path
|
||||
def applies?(scope, path, type)
|
||||
applies_type?(scope, type) && applies_path?(scope, path)
|
||||
end
|
||||
|
||||
def applies_path?(scope, path)
|
||||
rel_scope_path = scope["path"]
|
||||
return true if !rel_scope_path.is_a?(String) || rel_scope_path.empty?
|
||||
|
||||
sanitized_path = sanitize_path(path)
|
||||
|
||||
if rel_scope_path.include?("*")
|
||||
glob_scope(sanitized_path, rel_scope_path)
|
||||
else
|
||||
path_is_subpath?(sanitized_path, strip_collections_dir(rel_scope_path))
|
||||
end
|
||||
end
|
||||
|
||||
def glob_scope(sanitized_path, rel_scope_path)
|
||||
site_source = Pathname.new(@site.source)
|
||||
abs_scope_path = site_source.join(rel_scope_path).to_s
|
||||
|
||||
glob_cache(abs_scope_path).each do |scope_path|
|
||||
scope_path = Pathname.new(scope_path).relative_path_from(site_source).to_s
|
||||
scope_path = strip_collections_dir(scope_path)
|
||||
Jekyll.logger.debug "Globbed Scope Path:", scope_path
|
||||
return true if path_is_subpath?(sanitized_path, scope_path)
|
||||
end
|
||||
false
|
||||
end
|
||||
|
||||
def glob_cache(path)
|
||||
@glob_cache ||= {}
|
||||
@glob_cache[path] ||= Dir.glob(path)
|
||||
end
|
||||
|
||||
def path_is_subpath?(path, parent_path)
|
||||
path.start_with?(parent_path)
|
||||
end
|
||||
|
||||
def strip_collections_dir(path)
|
||||
collections_dir = @site.config["collections_dir"]
|
||||
slashed_coll_dir = collections_dir.empty? ? "/" : "#{collections_dir}/"
|
||||
return path if collections_dir.empty? || !path.to_s.start_with?(slashed_coll_dir)
|
||||
|
||||
path.sub(slashed_coll_dir, "")
|
||||
end
|
||||
|
||||
# Determines whether the scope applies to type.
|
||||
# The scope applies to the type if:
|
||||
# 1. no 'type' is specified
|
||||
# 2. the 'type' in the scope is the same as the type asked about
|
||||
#
|
||||
# scope - the Hash defaults set being asked about application
|
||||
# type - the type of the document being processed / asked about
|
||||
# its defaults.
|
||||
#
|
||||
# Returns true if either of the above conditions are satisfied,
|
||||
# otherwise returns false
|
||||
def applies_type?(scope, type)
|
||||
!scope.key?("type") || type&.to_sym.eql?(scope["type"].to_sym)
|
||||
end
|
||||
|
||||
# Checks if a given set of default values is valid
|
||||
#
|
||||
# set - the default value hash, as defined in _config.yml
|
||||
#
|
||||
# Returns true if the set is valid and can be used in this class
|
||||
def valid?(set)
|
||||
set.is_a?(Hash) && set["values"].is_a?(Hash)
|
||||
end
|
||||
|
||||
# Determines if a new scope has precedence over an old one
|
||||
#
|
||||
# old_scope - the old scope hash, or nil if there's none
|
||||
# new_scope - the new scope hash
|
||||
#
|
||||
# Returns true if the new scope has precedence over the older
|
||||
# rubocop: disable Naming/PredicateName
|
||||
def has_precedence?(old_scope, new_scope)
|
||||
return true if old_scope.nil?
|
||||
|
||||
new_path = sanitize_path(new_scope["path"])
|
||||
old_path = sanitize_path(old_scope["path"])
|
||||
|
||||
if new_path.length != old_path.length
|
||||
new_path.length >= old_path.length
|
||||
elsif new_scope.key?("type")
|
||||
true
|
||||
else
|
||||
!old_scope.key? "type"
|
||||
end
|
||||
end
|
||||
# rubocop: enable Naming/PredicateName
|
||||
|
||||
# Collects a list of sets that match the given path and type
|
||||
#
|
||||
# Returns an array of hashes
|
||||
def matching_sets(path, type)
|
||||
@matched_set_cache ||= {}
|
||||
@matched_set_cache[path] ||= {}
|
||||
@matched_set_cache[path][type] ||= begin
|
||||
valid_sets.select do |set|
|
||||
!set.key?("scope") || applies?(set["scope"], path, type)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Returns a list of valid sets
|
||||
#
|
||||
# This is not cached to allow plugins to modify the configuration
|
||||
# and have their changes take effect
|
||||
#
|
||||
# Returns an array of hashes
|
||||
def valid_sets
|
||||
sets = @site.config["defaults"]
|
||||
return [] unless sets.is_a?(Array)
|
||||
|
||||
sets.map do |set|
|
||||
if valid?(set)
|
||||
ensure_time!(update_deprecated_types(set))
|
||||
else
|
||||
Jekyll.logger.warn "Defaults:", "An invalid front-matter default set was found:"
|
||||
Jekyll.logger.warn set.to_s
|
||||
nil
|
||||
end
|
||||
end.tap(&:compact!)
|
||||
end
|
||||
|
||||
# Sanitizes the given path by removing a leading slash
|
||||
def sanitize_path(path)
|
||||
if path.nil? || path.empty?
|
||||
""
|
||||
elsif path.start_with?("/")
|
||||
path.gsub(%r!\A/|(?<=[^/])\z!, "")
|
||||
else
|
||||
path
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
5
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/generator.rb
vendored
Normal file
5
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/generator.rb
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Jekyll
|
||||
Generator = Class.new(Plugin)
|
||||
end
|
||||
107
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/hooks.rb
vendored
Normal file
107
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/hooks.rb
vendored
Normal file
@@ -0,0 +1,107 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Jekyll
|
||||
module Hooks
|
||||
DEFAULT_PRIORITY = 20
|
||||
|
||||
# compatibility layer for octopress-hooks users
|
||||
PRIORITY_MAP = {
|
||||
:low => 10,
|
||||
:normal => 20,
|
||||
:high => 30,
|
||||
}.freeze
|
||||
|
||||
# initial empty hooks
|
||||
@registry = {
|
||||
:site => {
|
||||
:after_init => [],
|
||||
:after_reset => [],
|
||||
:post_read => [],
|
||||
:pre_render => [],
|
||||
:post_render => [],
|
||||
:post_write => [],
|
||||
},
|
||||
:pages => {
|
||||
:post_init => [],
|
||||
:pre_render => [],
|
||||
:post_convert => [],
|
||||
:post_render => [],
|
||||
:post_write => [],
|
||||
},
|
||||
:posts => {
|
||||
:post_init => [],
|
||||
:pre_render => [],
|
||||
:post_convert => [],
|
||||
:post_render => [],
|
||||
:post_write => [],
|
||||
},
|
||||
:documents => {
|
||||
:post_init => [],
|
||||
:pre_render => [],
|
||||
:post_convert => [],
|
||||
:post_render => [],
|
||||
:post_write => [],
|
||||
},
|
||||
:clean => {
|
||||
:on_obsolete => [],
|
||||
},
|
||||
}
|
||||
|
||||
# map of all hooks and their priorities
|
||||
@hook_priority = {}
|
||||
|
||||
NotAvailable = Class.new(RuntimeError)
|
||||
Uncallable = Class.new(RuntimeError)
|
||||
|
||||
# register hook(s) to be called later, public API
|
||||
def self.register(owners, event, priority: DEFAULT_PRIORITY, &block)
|
||||
Array(owners).each do |owner|
|
||||
register_one(owner, event, priority_value(priority), &block)
|
||||
end
|
||||
end
|
||||
|
||||
# Ensure the priority is a Fixnum
|
||||
def self.priority_value(priority)
|
||||
return priority if priority.is_a?(Integer)
|
||||
|
||||
PRIORITY_MAP[priority] || DEFAULT_PRIORITY
|
||||
end
|
||||
|
||||
# register a single hook to be called later, internal API
|
||||
def self.register_one(owner, event, priority, &block)
|
||||
@registry[owner] ||= {
|
||||
:post_init => [],
|
||||
:pre_render => [],
|
||||
:post_convert => [],
|
||||
:post_render => [],
|
||||
:post_write => [],
|
||||
}
|
||||
|
||||
unless @registry[owner][event]
|
||||
raise NotAvailable, "Invalid hook. #{owner} supports only the " \
|
||||
"following hooks #{@registry[owner].keys.inspect}"
|
||||
end
|
||||
|
||||
raise Uncallable, "Hooks must respond to :call" unless block.respond_to? :call
|
||||
|
||||
insert_hook owner, event, priority, &block
|
||||
end
|
||||
|
||||
def self.insert_hook(owner, event, priority, &block)
|
||||
@hook_priority[block] = [-priority, @hook_priority.size]
|
||||
@registry[owner][event] << block
|
||||
end
|
||||
|
||||
# interface for Jekyll core components to trigger hooks
|
||||
def self.trigger(owner, event, *args)
|
||||
# proceed only if there are hooks to call
|
||||
hooks = @registry.dig(owner, event)
|
||||
return if hooks.nil? || hooks.empty?
|
||||
|
||||
# sort and call hooks according to priority and load order
|
||||
hooks.sort_by { |h| @hook_priority[h] }.each do |hook|
|
||||
hook.call(*args)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
32
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/inclusion.rb
vendored
Normal file
32
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/inclusion.rb
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Jekyll
|
||||
class Inclusion
|
||||
attr_reader :site, :name, :path
|
||||
private :site
|
||||
|
||||
def initialize(site, base, name)
|
||||
@site = site
|
||||
@name = name
|
||||
@path = PathManager.join(base, name)
|
||||
end
|
||||
|
||||
def render(context)
|
||||
@template ||= site.liquid_renderer.file(path).parse(content)
|
||||
@template.render!(context)
|
||||
rescue Liquid::Error => e
|
||||
e.template_name = path
|
||||
e.markup_context = "included " if e.markup_context.nil?
|
||||
raise e
|
||||
end
|
||||
|
||||
def content
|
||||
@content ||= File.read(path, **site.file_read_opts)
|
||||
end
|
||||
|
||||
def inspect
|
||||
"#{self.class} #{path.inspect}"
|
||||
end
|
||||
alias_method :to_s, :inspect
|
||||
end
|
||||
end
|
||||
67
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/layout.rb
vendored
Normal file
67
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/layout.rb
vendored
Normal file
@@ -0,0 +1,67 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Jekyll
|
||||
class Layout
|
||||
include Convertible
|
||||
|
||||
# Gets the Site object.
|
||||
attr_reader :site
|
||||
|
||||
# Gets the name of this layout.
|
||||
attr_reader :name
|
||||
|
||||
# Gets the path to this layout.
|
||||
attr_reader :path
|
||||
|
||||
# Gets the path to this layout relative to its base
|
||||
attr_reader :relative_path
|
||||
|
||||
# Gets/Sets the extension of this layout.
|
||||
attr_accessor :ext
|
||||
|
||||
# Gets/Sets the Hash that holds the metadata for this layout.
|
||||
attr_accessor :data
|
||||
|
||||
# Gets/Sets the content of this layout.
|
||||
attr_accessor :content
|
||||
|
||||
# Initialize a new Layout.
|
||||
#
|
||||
# site - The Site.
|
||||
# base - The String path to the source.
|
||||
# name - The String filename of the post file.
|
||||
def initialize(site, base, name)
|
||||
@site = site
|
||||
@base = base
|
||||
@name = name
|
||||
|
||||
if site.theme && site.theme.layouts_path.eql?(base)
|
||||
@base_dir = site.theme.root
|
||||
@path = site.in_theme_dir(base, name)
|
||||
else
|
||||
@base_dir = site.source
|
||||
@path = site.in_source_dir(base, name)
|
||||
end
|
||||
@relative_path = @path.sub(@base_dir, "")
|
||||
|
||||
self.data = {}
|
||||
|
||||
process(name)
|
||||
read_yaml(base, name)
|
||||
end
|
||||
|
||||
# Extract information from the layout filename.
|
||||
#
|
||||
# name - The String filename of the layout file.
|
||||
#
|
||||
# Returns nothing.
|
||||
def process(name)
|
||||
self.ext = File.extname(name)
|
||||
end
|
||||
|
||||
# Returns the object as a debug String.
|
||||
def inspect
|
||||
"#<#{self.class} @path=#{@path.inspect}>"
|
||||
end
|
||||
end
|
||||
end
|
||||
22
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/liquid_extensions.rb
vendored
Normal file
22
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/liquid_extensions.rb
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Jekyll
|
||||
module LiquidExtensions
|
||||
# Lookup a Liquid variable in the given context.
|
||||
#
|
||||
# context - the Liquid context in question.
|
||||
# variable - the variable name, as a string.
|
||||
#
|
||||
# Returns the value of the variable in the context
|
||||
# or the variable name if not found.
|
||||
def lookup_variable(context, variable)
|
||||
lookup = context
|
||||
|
||||
variable.split(".").each do |value|
|
||||
lookup = lookup[value]
|
||||
end
|
||||
|
||||
lookup || variable
|
||||
end
|
||||
end
|
||||
end
|
||||
80
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/liquid_renderer.rb
vendored
Normal file
80
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/liquid_renderer.rb
vendored
Normal file
@@ -0,0 +1,80 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require_relative "liquid_renderer/file"
|
||||
require_relative "liquid_renderer/table"
|
||||
|
||||
module Jekyll
|
||||
class LiquidRenderer
|
||||
def initialize(site)
|
||||
@site = site
|
||||
Liquid::Template.error_mode = @site.config["liquid"]["error_mode"].to_sym
|
||||
reset
|
||||
end
|
||||
|
||||
def reset
|
||||
@stats = {}
|
||||
@cache = {}
|
||||
end
|
||||
|
||||
def file(filename)
|
||||
filename = normalize_path(filename)
|
||||
LiquidRenderer::File.new(self, filename).tap do
|
||||
@stats[filename] ||= new_profile_hash
|
||||
end
|
||||
end
|
||||
|
||||
def increment_bytes(filename, bytes)
|
||||
@stats[filename][:bytes] += bytes
|
||||
end
|
||||
|
||||
def increment_time(filename, time)
|
||||
@stats[filename][:time] += time
|
||||
end
|
||||
|
||||
def increment_count(filename)
|
||||
@stats[filename][:count] += 1
|
||||
end
|
||||
|
||||
def stats_table(num_of_rows = 50)
|
||||
LiquidRenderer::Table.new(@stats).to_s(num_of_rows)
|
||||
end
|
||||
|
||||
def self.format_error(error, path)
|
||||
"#{error.message} in #{path}"
|
||||
end
|
||||
|
||||
# A persistent cache to store and retrieve parsed templates based on the filename
|
||||
# via `LiquidRenderer::File#parse`
|
||||
#
|
||||
# It is emptied when `self.reset` is called.
|
||||
def cache
|
||||
@cache ||= {}
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def normalize_path(filename)
|
||||
@normalize_path ||= {}
|
||||
@normalize_path[filename] ||= begin
|
||||
theme_dir = @site.theme&.root
|
||||
case filename
|
||||
when %r!\A(#{Regexp.escape(@site.source)}/)(?<rest>.*)!io
|
||||
Regexp.last_match(:rest)
|
||||
when %r!(/gems/.*)*/gems/(?<dirname>[^/]+)(?<rest>.*)!,
|
||||
%r!(?<dirname>[^/]+/lib)(?<rest>.*)!
|
||||
"#{Regexp.last_match(:dirname)}#{Regexp.last_match(:rest)}"
|
||||
when theme_dir && %r!\A#{Regexp.escape(theme_dir)}/(?<rest>.*)!io
|
||||
PathManager.join(@site.theme.basename, Regexp.last_match(:rest))
|
||||
when %r!\A/(.*)!
|
||||
Regexp.last_match(1)
|
||||
else
|
||||
filename
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def new_profile_hash
|
||||
Hash.new { |hash, key| hash[key] = 0 }
|
||||
end
|
||||
end
|
||||
end
|
||||
77
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/liquid_renderer/file.rb
vendored
Normal file
77
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/liquid_renderer/file.rb
vendored
Normal file
@@ -0,0 +1,77 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Jekyll
|
||||
class LiquidRenderer
|
||||
class File
|
||||
def initialize(renderer, filename)
|
||||
@renderer = renderer
|
||||
@filename = filename
|
||||
end
|
||||
|
||||
def parse(content)
|
||||
measure_time do
|
||||
@renderer.cache[@filename] ||= Liquid::Template.parse(content, :line_numbers => true)
|
||||
end
|
||||
@template = @renderer.cache[@filename]
|
||||
|
||||
self
|
||||
end
|
||||
|
||||
def render(*args)
|
||||
reset_template_assigns
|
||||
|
||||
measure_time do
|
||||
measure_bytes do
|
||||
measure_counts do
|
||||
@template.render(*args)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# This method simply 'rethrows any error' before attempting to render the template.
|
||||
def render!(*args)
|
||||
reset_template_assigns
|
||||
|
||||
measure_time do
|
||||
measure_bytes do
|
||||
measure_counts do
|
||||
@template.render!(*args)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def warnings
|
||||
@template.warnings
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# clear assigns to `Liquid::Template` instance prior to rendering since
|
||||
# `Liquid::Template` instances are cached in Jekyll 4.
|
||||
def reset_template_assigns
|
||||
@template.instance_assigns.clear
|
||||
end
|
||||
|
||||
def measure_counts
|
||||
@renderer.increment_count(@filename)
|
||||
yield
|
||||
end
|
||||
|
||||
def measure_bytes
|
||||
yield.tap do |str|
|
||||
@renderer.increment_bytes(@filename, str.bytesize)
|
||||
end
|
||||
end
|
||||
|
||||
def measure_time
|
||||
before = Time.now
|
||||
yield
|
||||
ensure
|
||||
after = Time.now
|
||||
@renderer.increment_time(@filename, after - before)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
55
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/liquid_renderer/table.rb
vendored
Normal file
55
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/liquid_renderer/table.rb
vendored
Normal file
@@ -0,0 +1,55 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Jekyll
|
||||
class LiquidRenderer
|
||||
class Table
|
||||
GAUGES = [:count, :bytes, :time].freeze
|
||||
|
||||
def initialize(stats)
|
||||
@stats = stats
|
||||
end
|
||||
|
||||
def to_s(num_of_rows = 50)
|
||||
Jekyll::Profiler.tabulate(data_for_table(num_of_rows))
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# rubocop:disable Metrics/AbcSize
|
||||
def data_for_table(num_of_rows)
|
||||
sorted = @stats.sort_by { |_, file_stats| -file_stats[:time] }
|
||||
sorted = sorted.slice(0, num_of_rows)
|
||||
|
||||
table = [header_labels]
|
||||
totals = Hash.new { |hash, key| hash[key] = 0 }
|
||||
|
||||
sorted.each do |filename, file_stats|
|
||||
GAUGES.each { |gauge| totals[gauge] += file_stats[gauge] }
|
||||
row = []
|
||||
row << filename
|
||||
row << file_stats[:count].to_s
|
||||
row << format_bytes(file_stats[:bytes])
|
||||
row << format("%.3f", file_stats[:time])
|
||||
table << row
|
||||
end
|
||||
|
||||
footer = []
|
||||
footer << "TOTAL (for #{sorted.size} files)"
|
||||
footer << totals[:count].to_s
|
||||
footer << format_bytes(totals[:bytes])
|
||||
footer << format("%.3f", totals[:time])
|
||||
table << footer
|
||||
end
|
||||
# rubocop:enable Metrics/AbcSize
|
||||
|
||||
def header_labels
|
||||
GAUGES.map { |gauge| gauge.to_s.capitalize }.unshift("Filename")
|
||||
end
|
||||
|
||||
def format_bytes(bytes)
|
||||
bytes /= 1024.0
|
||||
format("%.2fK", bytes)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
151
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/log_adapter.rb
vendored
Normal file
151
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/log_adapter.rb
vendored
Normal file
@@ -0,0 +1,151 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Jekyll
|
||||
class LogAdapter
|
||||
attr_reader :writer, :messages, :level
|
||||
|
||||
LOG_LEVELS = {
|
||||
:debug => ::Logger::DEBUG,
|
||||
:info => ::Logger::INFO,
|
||||
:warn => ::Logger::WARN,
|
||||
:error => ::Logger::ERROR,
|
||||
}.freeze
|
||||
|
||||
# Public: Create a new instance of a log writer
|
||||
#
|
||||
# writer - Logger compatible instance
|
||||
# log_level - (optional, symbol) the log level
|
||||
#
|
||||
# Returns nothing
|
||||
def initialize(writer, level = :info)
|
||||
@messages = []
|
||||
@writer = writer
|
||||
self.log_level = level
|
||||
end
|
||||
|
||||
# Public: Set the log level on the writer
|
||||
#
|
||||
# level - (symbol) the log level
|
||||
#
|
||||
# Returns nothing
|
||||
def log_level=(level)
|
||||
writer.level = level if level.is_a?(Integer) && level.between?(0, 3)
|
||||
writer.level = LOG_LEVELS[level] ||
|
||||
raise(ArgumentError, "unknown log level")
|
||||
@level = level
|
||||
end
|
||||
|
||||
def adjust_verbosity(options = {})
|
||||
# Quiet always wins.
|
||||
if options[:quiet]
|
||||
self.log_level = :error
|
||||
elsif options[:verbose]
|
||||
self.log_level = :debug
|
||||
end
|
||||
debug "Logging at level:", LOG_LEVELS.key(writer.level).to_s
|
||||
debug "Jekyll Version:", Jekyll::VERSION
|
||||
end
|
||||
|
||||
# Public: Print a debug message
|
||||
#
|
||||
# topic - the topic of the message, e.g. "Configuration file", "Deprecation", etc.
|
||||
# message - the message detail
|
||||
#
|
||||
# Returns nothing
|
||||
def debug(topic, message = nil, &block)
|
||||
write(:debug, topic, message, &block)
|
||||
end
|
||||
|
||||
# Public: Print a message
|
||||
#
|
||||
# topic - the topic of the message, e.g. "Configuration file", "Deprecation", etc.
|
||||
# message - the message detail
|
||||
#
|
||||
# Returns nothing
|
||||
def info(topic, message = nil, &block)
|
||||
write(:info, topic, message, &block)
|
||||
end
|
||||
|
||||
# Public: Print a message
|
||||
#
|
||||
# topic - the topic of the message, e.g. "Configuration file", "Deprecation", etc.
|
||||
# message - the message detail
|
||||
#
|
||||
# Returns nothing
|
||||
def warn(topic, message = nil, &block)
|
||||
write(:warn, topic, message, &block)
|
||||
end
|
||||
|
||||
# Public: Print an error message
|
||||
#
|
||||
# topic - the topic of the message, e.g. "Configuration file", "Deprecation", etc.
|
||||
# message - the message detail
|
||||
#
|
||||
# Returns nothing
|
||||
def error(topic, message = nil, &block)
|
||||
write(:error, topic, message, &block)
|
||||
end
|
||||
|
||||
# Public: Print an error message and immediately abort the process
|
||||
#
|
||||
# topic - the topic of the message, e.g. "Configuration file", "Deprecation", etc.
|
||||
# message - the message detail (can be omitted)
|
||||
#
|
||||
# Returns nothing
|
||||
def abort_with(topic, message = nil, &block)
|
||||
error(topic, message, &block)
|
||||
abort
|
||||
end
|
||||
|
||||
# Internal: Build a topic method
|
||||
#
|
||||
# topic - the topic of the message, e.g. "Configuration file", "Deprecation", etc.
|
||||
# message - the message detail
|
||||
#
|
||||
# Returns the formatted message
|
||||
def message(topic, message = nil)
|
||||
raise ArgumentError, "block or message, not both" if block_given? && message
|
||||
|
||||
message = yield if block_given?
|
||||
message = message.to_s.gsub(%r!\s+!, " ")
|
||||
topic = formatted_topic(topic, block_given?)
|
||||
out = topic + message
|
||||
messages << out
|
||||
out
|
||||
end
|
||||
|
||||
# Internal: Format the topic
|
||||
#
|
||||
# topic - the topic of the message, e.g. "Configuration file", "Deprecation", etc.
|
||||
# colon -
|
||||
#
|
||||
# Returns the formatted topic statement
|
||||
def formatted_topic(topic, colon = false)
|
||||
"#{topic}#{colon ? ": " : " "}".rjust(20)
|
||||
end
|
||||
|
||||
# Internal: Check if the message should be written given the log level.
|
||||
#
|
||||
# level_of_message - the Symbol level of message, one of :debug, :info, :warn, :error
|
||||
#
|
||||
# Returns whether the message should be written.
|
||||
def write_message?(level_of_message)
|
||||
LOG_LEVELS.fetch(level) <= LOG_LEVELS.fetch(level_of_message)
|
||||
end
|
||||
|
||||
# Internal: Log a message.
|
||||
#
|
||||
# level_of_message - the Symbol level of message, one of :debug, :info, :warn, :error
|
||||
# topic - the String topic or full message
|
||||
# message - the String message (optional)
|
||||
# block - a block containing the message (optional)
|
||||
#
|
||||
# Returns false if the message was not written, otherwise returns the value of calling
|
||||
# the appropriate writer method, e.g. writer.info.
|
||||
def write(level_of_message, topic, message = nil, &block)
|
||||
return false unless write_message?(level_of_message)
|
||||
|
||||
writer.public_send(level_of_message, message(topic, message, &block))
|
||||
end
|
||||
end
|
||||
end
|
||||
867
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/mime.types
vendored
Normal file
867
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/mime.types
vendored
Normal file
@@ -0,0 +1,867 @@
|
||||
# Woah there. Do not edit this file directly.
|
||||
# This file is generated automatically by script/vendor-mimes.
|
||||
|
||||
application/andrew-inset ez
|
||||
application/applixware aw
|
||||
application/atom+xml atom
|
||||
application/atomcat+xml atomcat
|
||||
application/atomsvc+xml atomsvc
|
||||
application/bdoc bdoc
|
||||
application/ccxml+xml ccxml
|
||||
application/cdmi-capability cdmia
|
||||
application/cdmi-container cdmic
|
||||
application/cdmi-domain cdmid
|
||||
application/cdmi-object cdmio
|
||||
application/cdmi-queue cdmiq
|
||||
application/cu-seeme cu
|
||||
application/dash+xml mpd
|
||||
application/davmount+xml davmount
|
||||
application/docbook+xml dbk
|
||||
application/dssc+der dssc
|
||||
application/dssc+xml xdssc
|
||||
application/ecmascript ecma es
|
||||
application/emma+xml emma
|
||||
application/epub+zip epub
|
||||
application/exi exi
|
||||
application/font-tdpfr pfr
|
||||
application/geo+json geojson
|
||||
application/gml+xml gml
|
||||
application/gpx+xml gpx
|
||||
application/gxf gxf
|
||||
application/gzip gz
|
||||
application/hjson hjson
|
||||
application/hyperstudio stk
|
||||
application/inkml+xml ink inkml
|
||||
application/ipfix ipfix
|
||||
application/java-archive jar war ear
|
||||
application/java-serialized-object ser
|
||||
application/java-vm class
|
||||
application/javascript js mjs
|
||||
application/json json map
|
||||
application/json5 json5
|
||||
application/jsonml+json jsonml
|
||||
application/ld+json jsonld
|
||||
application/lost+xml lostxml
|
||||
application/mac-binhex40 hqx
|
||||
application/mac-compactpro cpt
|
||||
application/mads+xml mads
|
||||
application/manifest+json webmanifest
|
||||
application/marc mrc
|
||||
application/marcxml+xml mrcx
|
||||
application/mathematica ma nb mb
|
||||
application/mathml+xml mathml
|
||||
application/mbox mbox
|
||||
application/mediaservercontrol+xml mscml
|
||||
application/metalink+xml metalink
|
||||
application/metalink4+xml meta4
|
||||
application/mets+xml mets
|
||||
application/mods+xml mods
|
||||
application/mp21 m21 mp21
|
||||
application/mp4 mp4s m4p
|
||||
application/msword doc dot
|
||||
application/mxf mxf
|
||||
application/n-quads nq
|
||||
application/n-triples nt
|
||||
application/octet-stream bin dms lrf mar so dist distz pkg bpk dump elc deploy exe dll deb dmg iso img msi msp msm buffer
|
||||
application/oda oda
|
||||
application/oebps-package+xml opf
|
||||
application/ogg ogx
|
||||
application/omdoc+xml omdoc
|
||||
application/onenote onetoc onetoc2 onetmp onepkg
|
||||
application/oxps oxps
|
||||
application/patch-ops-error+xml xer
|
||||
application/pdf pdf
|
||||
application/pgp-encrypted pgp
|
||||
application/pgp-signature asc sig
|
||||
application/pics-rules prf
|
||||
application/pkcs10 p10
|
||||
application/pkcs7-mime p7m p7c
|
||||
application/pkcs7-signature p7s
|
||||
application/pkcs8 p8
|
||||
application/pkix-attr-cert ac
|
||||
application/pkix-cert cer
|
||||
application/pkix-crl crl
|
||||
application/pkix-pkipath pkipath
|
||||
application/pkixcmp pki
|
||||
application/pls+xml pls
|
||||
application/postscript ai eps ps
|
||||
application/prs.cww cww
|
||||
application/pskc+xml pskcxml
|
||||
application/raml+yaml raml
|
||||
application/rdf+xml rdf owl
|
||||
application/reginfo+xml rif
|
||||
application/relax-ng-compact-syntax rnc
|
||||
application/resource-lists+xml rl
|
||||
application/resource-lists-diff+xml rld
|
||||
application/rls-services+xml rs
|
||||
application/rpki-ghostbusters gbr
|
||||
application/rpki-manifest mft
|
||||
application/rpki-roa roa
|
||||
application/rsd+xml rsd
|
||||
application/rss+xml rss
|
||||
application/rtf rtf
|
||||
application/sbml+xml sbml
|
||||
application/scvp-cv-request scq
|
||||
application/scvp-cv-response scs
|
||||
application/scvp-vp-request spq
|
||||
application/scvp-vp-response spp
|
||||
application/sdp sdp
|
||||
application/set-payment-initiation setpay
|
||||
application/set-registration-initiation setreg
|
||||
application/shf+xml shf
|
||||
application/sieve siv sieve
|
||||
application/smil+xml smi smil
|
||||
application/sparql-query rq
|
||||
application/sparql-results+xml srx
|
||||
application/srgs gram
|
||||
application/srgs+xml grxml
|
||||
application/sru+xml sru
|
||||
application/ssdl+xml ssdl
|
||||
application/ssml+xml ssml
|
||||
application/tei+xml tei teicorpus
|
||||
application/thraud+xml tfi
|
||||
application/timestamped-data tsd
|
||||
application/vnd.3gpp.pic-bw-large plb
|
||||
application/vnd.3gpp.pic-bw-small psb
|
||||
application/vnd.3gpp.pic-bw-var pvb
|
||||
application/vnd.3gpp2.tcap tcap
|
||||
application/vnd.3m.post-it-notes pwn
|
||||
application/vnd.accpac.simply.aso aso
|
||||
application/vnd.accpac.simply.imp imp
|
||||
application/vnd.acucobol acu
|
||||
application/vnd.acucorp atc acutc
|
||||
application/vnd.adobe.air-application-installer-package+zip air
|
||||
application/vnd.adobe.formscentral.fcdt fcdt
|
||||
application/vnd.adobe.fxp fxp fxpl
|
||||
application/vnd.adobe.xdp+xml xdp
|
||||
application/vnd.adobe.xfdf xfdf
|
||||
application/vnd.ahead.space ahead
|
||||
application/vnd.airzip.filesecure.azf azf
|
||||
application/vnd.airzip.filesecure.azs azs
|
||||
application/vnd.amazon.ebook azw
|
||||
application/vnd.americandynamics.acc acc
|
||||
application/vnd.amiga.ami ami
|
||||
application/vnd.android.package-archive apk
|
||||
application/vnd.anser-web-certificate-issue-initiation cii
|
||||
application/vnd.anser-web-funds-transfer-initiation fti
|
||||
application/vnd.antix.game-component atx
|
||||
application/vnd.apple.installer+xml mpkg
|
||||
application/vnd.apple.keynote keynote
|
||||
application/vnd.apple.mpegurl m3u8
|
||||
application/vnd.apple.numbers numbers
|
||||
application/vnd.apple.pages pages
|
||||
application/vnd.apple.pkpass pkpass
|
||||
application/vnd.aristanetworks.swi swi
|
||||
application/vnd.astraea-software.iota iota
|
||||
application/vnd.audiograph aep
|
||||
application/vnd.blueice.multipass mpm
|
||||
application/vnd.bmi bmi
|
||||
application/vnd.businessobjects rep
|
||||
application/vnd.chemdraw+xml cdxml
|
||||
application/vnd.chipnuts.karaoke-mmd mmd
|
||||
application/vnd.cinderella cdy
|
||||
application/vnd.citationstyles.style+xml csl
|
||||
application/vnd.claymore cla
|
||||
application/vnd.cloanto.rp9 rp9
|
||||
application/vnd.clonk.c4group c4g c4d c4f c4p c4u
|
||||
application/vnd.cluetrust.cartomobile-config c11amc
|
||||
application/vnd.cluetrust.cartomobile-config-pkg c11amz
|
||||
application/vnd.commonspace csp
|
||||
application/vnd.contact.cmsg cdbcmsg
|
||||
application/vnd.cosmocaller cmc
|
||||
application/vnd.crick.clicker clkx
|
||||
application/vnd.crick.clicker.keyboard clkk
|
||||
application/vnd.crick.clicker.palette clkp
|
||||
application/vnd.crick.clicker.template clkt
|
||||
application/vnd.crick.clicker.wordbank clkw
|
||||
application/vnd.criticaltools.wbs+xml wbs
|
||||
application/vnd.ctc-posml pml
|
||||
application/vnd.cups-ppd ppd
|
||||
application/vnd.curl.car car
|
||||
application/vnd.curl.pcurl pcurl
|
||||
application/vnd.dart dart
|
||||
application/vnd.data-vision.rdz rdz
|
||||
application/vnd.dece.data uvf uvvf uvd uvvd
|
||||
application/vnd.dece.ttml+xml uvt uvvt
|
||||
application/vnd.dece.unspecified uvx uvvx
|
||||
application/vnd.dece.zip uvz uvvz
|
||||
application/vnd.denovo.fcselayout-link fe_launch
|
||||
application/vnd.dna dna
|
||||
application/vnd.dolby.mlp mlp
|
||||
application/vnd.dpgraph dpg
|
||||
application/vnd.dreamfactory dfac
|
||||
application/vnd.ds-keypoint kpxx
|
||||
application/vnd.dvb.ait ait
|
||||
application/vnd.dvb.service svc
|
||||
application/vnd.dynageo geo
|
||||
application/vnd.ecowin.chart mag
|
||||
application/vnd.enliven nml
|
||||
application/vnd.epson.esf esf
|
||||
application/vnd.epson.msf msf
|
||||
application/vnd.epson.quickanime qam
|
||||
application/vnd.epson.salt slt
|
||||
application/vnd.epson.ssf ssf
|
||||
application/vnd.eszigno3+xml es3 et3
|
||||
application/vnd.ezpix-album ez2
|
||||
application/vnd.ezpix-package ez3
|
||||
application/vnd.fdf fdf
|
||||
application/vnd.fdsn.mseed mseed
|
||||
application/vnd.fdsn.seed seed dataless
|
||||
application/vnd.flographit gph
|
||||
application/vnd.fluxtime.clip ftc
|
||||
application/vnd.framemaker fm frame maker book
|
||||
application/vnd.frogans.fnc fnc
|
||||
application/vnd.frogans.ltf ltf
|
||||
application/vnd.fsc.weblaunch fsc
|
||||
application/vnd.fujitsu.oasys oas
|
||||
application/vnd.fujitsu.oasys2 oa2
|
||||
application/vnd.fujitsu.oasys3 oa3
|
||||
application/vnd.fujitsu.oasysgp fg5
|
||||
application/vnd.fujitsu.oasysprs bh2
|
||||
application/vnd.fujixerox.ddd ddd
|
||||
application/vnd.fujixerox.docuworks xdw
|
||||
application/vnd.fujixerox.docuworks.binder xbd
|
||||
application/vnd.fuzzysheet fzs
|
||||
application/vnd.genomatix.tuxedo txd
|
||||
application/vnd.geogebra.file ggb
|
||||
application/vnd.geogebra.tool ggt
|
||||
application/vnd.geometry-explorer gex gre
|
||||
application/vnd.geonext gxt
|
||||
application/vnd.geoplan g2w
|
||||
application/vnd.geospace g3w
|
||||
application/vnd.gmx gmx
|
||||
application/vnd.google-apps.document gdoc
|
||||
application/vnd.google-apps.presentation gslides
|
||||
application/vnd.google-apps.spreadsheet gsheet
|
||||
application/vnd.google-earth.kml+xml kml
|
||||
application/vnd.google-earth.kmz kmz
|
||||
application/vnd.grafeq gqf gqs
|
||||
application/vnd.groove-account gac
|
||||
application/vnd.groove-help ghf
|
||||
application/vnd.groove-identity-message gim
|
||||
application/vnd.groove-injector grv
|
||||
application/vnd.groove-tool-message gtm
|
||||
application/vnd.groove-tool-template tpl
|
||||
application/vnd.groove-vcard vcg
|
||||
application/vnd.hal+xml hal
|
||||
application/vnd.handheld-entertainment+xml zmm
|
||||
application/vnd.hbci hbci
|
||||
application/vnd.hhe.lesson-player les
|
||||
application/vnd.hp-hpgl hpgl
|
||||
application/vnd.hp-hpid hpid
|
||||
application/vnd.hp-hps hps
|
||||
application/vnd.hp-jlyt jlt
|
||||
application/vnd.hp-pcl pcl
|
||||
application/vnd.hp-pclxl pclxl
|
||||
application/vnd.hydrostatix.sof-data sfd-hdstx
|
||||
application/vnd.ibm.minipay mpy
|
||||
application/vnd.ibm.modcap afp listafp list3820
|
||||
application/vnd.ibm.rights-management irm
|
||||
application/vnd.ibm.secure-container sc
|
||||
application/vnd.iccprofile icc icm
|
||||
application/vnd.igloader igl
|
||||
application/vnd.immervision-ivp ivp
|
||||
application/vnd.immervision-ivu ivu
|
||||
application/vnd.insors.igm igm
|
||||
application/vnd.intercon.formnet xpw xpx
|
||||
application/vnd.intergeo i2g
|
||||
application/vnd.intu.qbo qbo
|
||||
application/vnd.intu.qfx qfx
|
||||
application/vnd.ipunplugged.rcprofile rcprofile
|
||||
application/vnd.irepository.package+xml irp
|
||||
application/vnd.is-xpr xpr
|
||||
application/vnd.isac.fcs fcs
|
||||
application/vnd.jam jam
|
||||
application/vnd.jcp.javame.midlet-rms rms
|
||||
application/vnd.jisp jisp
|
||||
application/vnd.joost.joda-archive joda
|
||||
application/vnd.kahootz ktz ktr
|
||||
application/vnd.kde.karbon karbon
|
||||
application/vnd.kde.kchart chrt
|
||||
application/vnd.kde.kformula kfo
|
||||
application/vnd.kde.kivio flw
|
||||
application/vnd.kde.kontour kon
|
||||
application/vnd.kde.kpresenter kpr kpt
|
||||
application/vnd.kde.kspread ksp
|
||||
application/vnd.kde.kword kwd kwt
|
||||
application/vnd.kenameaapp htke
|
||||
application/vnd.kidspiration kia
|
||||
application/vnd.kinar kne knp
|
||||
application/vnd.koan skp skd skt skm
|
||||
application/vnd.kodak-descriptor sse
|
||||
application/vnd.las.las+xml lasxml
|
||||
application/vnd.llamagraphics.life-balance.desktop lbd
|
||||
application/vnd.llamagraphics.life-balance.exchange+xml lbe
|
||||
application/vnd.lotus-1-2-3 123
|
||||
application/vnd.lotus-approach apr
|
||||
application/vnd.lotus-freelance pre
|
||||
application/vnd.lotus-notes nsf
|
||||
application/vnd.lotus-organizer org
|
||||
application/vnd.lotus-screencam scm
|
||||
application/vnd.lotus-wordpro lwp
|
||||
application/vnd.macports.portpkg portpkg
|
||||
application/vnd.mcd mcd
|
||||
application/vnd.medcalcdata mc1
|
||||
application/vnd.mediastation.cdkey cdkey
|
||||
application/vnd.mfer mwf
|
||||
application/vnd.mfmp mfm
|
||||
application/vnd.micrografx.flo flo
|
||||
application/vnd.micrografx.igx igx
|
||||
application/vnd.mif mif
|
||||
application/vnd.mobius.daf daf
|
||||
application/vnd.mobius.dis dis
|
||||
application/vnd.mobius.mbk mbk
|
||||
application/vnd.mobius.mqy mqy
|
||||
application/vnd.mobius.msl msl
|
||||
application/vnd.mobius.plc plc
|
||||
application/vnd.mobius.txf txf
|
||||
application/vnd.mophun.application mpn
|
||||
application/vnd.mophun.certificate mpc
|
||||
application/vnd.mozilla.xul+xml xul
|
||||
application/vnd.ms-artgalry cil
|
||||
application/vnd.ms-cab-compressed cab
|
||||
application/vnd.ms-excel xls xlm xla xlc xlt xlw
|
||||
application/vnd.ms-excel.addin.macroenabled.12 xlam
|
||||
application/vnd.ms-excel.sheet.binary.macroenabled.12 xlsb
|
||||
application/vnd.ms-excel.sheet.macroenabled.12 xlsm
|
||||
application/vnd.ms-excel.template.macroenabled.12 xltm
|
||||
application/vnd.ms-fontobject eot
|
||||
application/vnd.ms-htmlhelp chm
|
||||
application/vnd.ms-ims ims
|
||||
application/vnd.ms-lrm lrm
|
||||
application/vnd.ms-officetheme thmx
|
||||
application/vnd.ms-outlook msg
|
||||
application/vnd.ms-pki.seccat cat
|
||||
application/vnd.ms-pki.stl stl
|
||||
application/vnd.ms-powerpoint ppt pps pot
|
||||
application/vnd.ms-powerpoint.addin.macroenabled.12 ppam
|
||||
application/vnd.ms-powerpoint.presentation.macroenabled.12 pptm
|
||||
application/vnd.ms-powerpoint.slide.macroenabled.12 sldm
|
||||
application/vnd.ms-powerpoint.slideshow.macroenabled.12 ppsm
|
||||
application/vnd.ms-powerpoint.template.macroenabled.12 potm
|
||||
application/vnd.ms-project mpp mpt
|
||||
application/vnd.ms-word.document.macroenabled.12 docm
|
||||
application/vnd.ms-word.template.macroenabled.12 dotm
|
||||
application/vnd.ms-works wps wks wcm wdb
|
||||
application/vnd.ms-wpl wpl
|
||||
application/vnd.ms-xpsdocument xps
|
||||
application/vnd.mseq mseq
|
||||
application/vnd.musician mus
|
||||
application/vnd.muvee.style msty
|
||||
application/vnd.mynfc taglet
|
||||
application/vnd.neurolanguage.nlu nlu
|
||||
application/vnd.nitf ntf nitf
|
||||
application/vnd.noblenet-directory nnd
|
||||
application/vnd.noblenet-sealer nns
|
||||
application/vnd.noblenet-web nnw
|
||||
application/vnd.nokia.n-gage.data ngdat
|
||||
application/vnd.nokia.n-gage.symbian.install n-gage
|
||||
application/vnd.nokia.radio-preset rpst
|
||||
application/vnd.nokia.radio-presets rpss
|
||||
application/vnd.novadigm.edm edm
|
||||
application/vnd.novadigm.edx edx
|
||||
application/vnd.novadigm.ext ext
|
||||
application/vnd.oasis.opendocument.chart odc
|
||||
application/vnd.oasis.opendocument.chart-template otc
|
||||
application/vnd.oasis.opendocument.database odb
|
||||
application/vnd.oasis.opendocument.formula odf
|
||||
application/vnd.oasis.opendocument.formula-template odft
|
||||
application/vnd.oasis.opendocument.graphics odg
|
||||
application/vnd.oasis.opendocument.graphics-template otg
|
||||
application/vnd.oasis.opendocument.image odi
|
||||
application/vnd.oasis.opendocument.image-template oti
|
||||
application/vnd.oasis.opendocument.presentation odp
|
||||
application/vnd.oasis.opendocument.presentation-template otp
|
||||
application/vnd.oasis.opendocument.spreadsheet ods
|
||||
application/vnd.oasis.opendocument.spreadsheet-template ots
|
||||
application/vnd.oasis.opendocument.text odt
|
||||
application/vnd.oasis.opendocument.text-master odm
|
||||
application/vnd.oasis.opendocument.text-template ott
|
||||
application/vnd.oasis.opendocument.text-web oth
|
||||
application/vnd.olpc-sugar xo
|
||||
application/vnd.oma.dd2+xml dd2
|
||||
application/vnd.openofficeorg.extension oxt
|
||||
application/vnd.openxmlformats-officedocument.presentationml.presentation pptx
|
||||
application/vnd.openxmlformats-officedocument.presentationml.slide sldx
|
||||
application/vnd.openxmlformats-officedocument.presentationml.slideshow ppsx
|
||||
application/vnd.openxmlformats-officedocument.presentationml.template potx
|
||||
application/vnd.openxmlformats-officedocument.spreadsheetml.sheet xlsx
|
||||
application/vnd.openxmlformats-officedocument.spreadsheetml.template xltx
|
||||
application/vnd.openxmlformats-officedocument.wordprocessingml.document docx
|
||||
application/vnd.openxmlformats-officedocument.wordprocessingml.template dotx
|
||||
application/vnd.osgeo.mapguide.package mgp
|
||||
application/vnd.osgi.dp dp
|
||||
application/vnd.osgi.subsystem esa
|
||||
application/vnd.palm pdb pqa oprc
|
||||
application/vnd.pawaafile paw
|
||||
application/vnd.pg.format str
|
||||
application/vnd.pg.osasli ei6
|
||||
application/vnd.picsel efif
|
||||
application/vnd.pmi.widget wg
|
||||
application/vnd.pocketlearn plf
|
||||
application/vnd.powerbuilder6 pbd
|
||||
application/vnd.previewsystems.box box
|
||||
application/vnd.proteus.magazine mgz
|
||||
application/vnd.publishare-delta-tree qps
|
||||
application/vnd.pvi.ptid1 ptid
|
||||
application/vnd.quark.quarkxpress qxd qxt qwd qwt qxl qxb
|
||||
application/vnd.realvnc.bed bed
|
||||
application/vnd.recordare.musicxml mxl
|
||||
application/vnd.recordare.musicxml+xml musicxml
|
||||
application/vnd.rig.cryptonote cryptonote
|
||||
application/vnd.rim.cod cod
|
||||
application/vnd.rn-realmedia rm
|
||||
application/vnd.rn-realmedia-vbr rmvb
|
||||
application/vnd.route66.link66+xml link66
|
||||
application/vnd.sailingtracker.track st
|
||||
application/vnd.seemail see
|
||||
application/vnd.sema sema
|
||||
application/vnd.semd semd
|
||||
application/vnd.semf semf
|
||||
application/vnd.shana.informed.formdata ifm
|
||||
application/vnd.shana.informed.formtemplate itp
|
||||
application/vnd.shana.informed.interchange iif
|
||||
application/vnd.shana.informed.package ipk
|
||||
application/vnd.simtech-mindmapper twd twds
|
||||
application/vnd.smaf mmf
|
||||
application/vnd.smart.teacher teacher
|
||||
application/vnd.solent.sdkm+xml sdkm sdkd
|
||||
application/vnd.spotfire.dxp dxp
|
||||
application/vnd.spotfire.sfs sfs
|
||||
application/vnd.stardivision.calc sdc
|
||||
application/vnd.stardivision.draw sda
|
||||
application/vnd.stardivision.impress sdd
|
||||
application/vnd.stardivision.math smf
|
||||
application/vnd.stardivision.writer sdw vor
|
||||
application/vnd.stardivision.writer-global sgl
|
||||
application/vnd.stepmania.package smzip
|
||||
application/vnd.stepmania.stepchart sm
|
||||
application/vnd.sun.wadl+xml wadl
|
||||
application/vnd.sun.xml.calc sxc
|
||||
application/vnd.sun.xml.calc.template stc
|
||||
application/vnd.sun.xml.draw sxd
|
||||
application/vnd.sun.xml.draw.template std
|
||||
application/vnd.sun.xml.impress sxi
|
||||
application/vnd.sun.xml.impress.template sti
|
||||
application/vnd.sun.xml.math sxm
|
||||
application/vnd.sun.xml.writer sxw
|
||||
application/vnd.sun.xml.writer.global sxg
|
||||
application/vnd.sun.xml.writer.template stw
|
||||
application/vnd.sus-calendar sus susp
|
||||
application/vnd.svd svd
|
||||
application/vnd.symbian.install sis sisx
|
||||
application/vnd.syncml+xml xsm
|
||||
application/vnd.syncml.dm+wbxml bdm
|
||||
application/vnd.syncml.dm+xml xdm
|
||||
application/vnd.tao.intent-module-archive tao
|
||||
application/vnd.tcpdump.pcap pcap cap dmp
|
||||
application/vnd.tmobile-livetv tmo
|
||||
application/vnd.trid.tpt tpt
|
||||
application/vnd.triscape.mxs mxs
|
||||
application/vnd.trueapp tra
|
||||
application/vnd.ufdl ufd ufdl
|
||||
application/vnd.uiq.theme utz
|
||||
application/vnd.umajin umj
|
||||
application/vnd.unity unityweb
|
||||
application/vnd.uoml+xml uoml
|
||||
application/vnd.vcx vcx
|
||||
application/vnd.visio vsd vst vss vsw
|
||||
application/vnd.visionary vis
|
||||
application/vnd.vsf vsf
|
||||
application/vnd.wap.wbxml wbxml
|
||||
application/vnd.wap.wmlc wmlc
|
||||
application/vnd.wap.wmlscriptc wmlsc
|
||||
application/vnd.webturbo wtb
|
||||
application/vnd.wolfram.player nbp
|
||||
application/vnd.wordperfect wpd
|
||||
application/vnd.wqd wqd
|
||||
application/vnd.wt.stf stf
|
||||
application/vnd.xara xar
|
||||
application/vnd.xfdl xfdl
|
||||
application/vnd.yamaha.hv-dic hvd
|
||||
application/vnd.yamaha.hv-script hvs
|
||||
application/vnd.yamaha.hv-voice hvp
|
||||
application/vnd.yamaha.openscoreformat osf
|
||||
application/vnd.yamaha.openscoreformat.osfpvg+xml osfpvg
|
||||
application/vnd.yamaha.smaf-audio saf
|
||||
application/vnd.yamaha.smaf-phrase spf
|
||||
application/vnd.yellowriver-custom-menu cmp
|
||||
application/vnd.zul zir zirz
|
||||
application/vnd.zzazz.deck+xml zaz
|
||||
application/voicexml+xml vxml
|
||||
application/wasm wasm
|
||||
application/widget wgt
|
||||
application/winhlp hlp
|
||||
application/wsdl+xml wsdl
|
||||
application/wspolicy+xml wspolicy
|
||||
application/x-7z-compressed 7z
|
||||
application/x-abiword abw
|
||||
application/x-ace-compressed ace
|
||||
application/x-arj arj
|
||||
application/x-authorware-bin aab x32 u32 vox
|
||||
application/x-authorware-map aam
|
||||
application/x-authorware-seg aas
|
||||
application/x-bcpio bcpio
|
||||
application/x-bittorrent torrent
|
||||
application/x-blorb blb blorb
|
||||
application/x-bzip bz
|
||||
application/x-bzip2 bz2 boz
|
||||
application/x-cbr cbr cba cbt cbz cb7
|
||||
application/x-cdlink vcd
|
||||
application/x-cfs-compressed cfs
|
||||
application/x-chat chat
|
||||
application/x-chess-pgn pgn
|
||||
application/x-chrome-extension crx
|
||||
application/x-cocoa cco
|
||||
application/x-conference nsc
|
||||
application/x-cpio cpio
|
||||
application/x-csh csh
|
||||
application/x-debian-package udeb
|
||||
application/x-dgc-compressed dgc
|
||||
application/x-director dir dcr dxr cst cct cxt w3d fgd swa
|
||||
application/x-doom wad
|
||||
application/x-dtbncx+xml ncx
|
||||
application/x-dtbook+xml dtb
|
||||
application/x-dtbresource+xml res
|
||||
application/x-dvi dvi
|
||||
application/x-envoy evy
|
||||
application/x-eva eva
|
||||
application/x-font-bdf bdf
|
||||
application/x-font-ghostscript gsf
|
||||
application/x-font-linux-psf psf
|
||||
application/x-font-pcf pcf
|
||||
application/x-font-snf snf
|
||||
application/x-font-type1 pfa pfb pfm afm
|
||||
application/x-freearc arc
|
||||
application/x-futuresplash spl
|
||||
application/x-gca-compressed gca
|
||||
application/x-glulx ulx
|
||||
application/x-gnumeric gnumeric
|
||||
application/x-gramps-xml gramps
|
||||
application/x-gtar gtar
|
||||
application/x-hdf hdf
|
||||
application/x-httpd-php php
|
||||
application/x-install-instructions install
|
||||
application/x-java-archive-diff jardiff
|
||||
application/x-java-jnlp-file jnlp
|
||||
application/x-latex latex
|
||||
application/x-lua-bytecode luac
|
||||
application/x-lzh-compressed lzh lha
|
||||
application/x-makeself run
|
||||
application/x-mie mie
|
||||
application/x-mobipocket-ebook prc mobi
|
||||
application/x-ms-application application
|
||||
application/x-ms-shortcut lnk
|
||||
application/x-ms-wmd wmd
|
||||
application/x-ms-wmz wmz
|
||||
application/x-ms-xbap xbap
|
||||
application/x-msaccess mdb
|
||||
application/x-msbinder obd
|
||||
application/x-mscardfile crd
|
||||
application/x-msclip clp
|
||||
application/x-msdownload com bat
|
||||
application/x-msmediaview mvb m13 m14
|
||||
application/x-msmetafile wmf emf emz
|
||||
application/x-msmoney mny
|
||||
application/x-mspublisher pub
|
||||
application/x-msschedule scd
|
||||
application/x-msterminal trm
|
||||
application/x-mswrite wri
|
||||
application/x-netcdf nc cdf
|
||||
application/x-ns-proxy-autoconfig pac
|
||||
application/x-nzb nzb
|
||||
application/x-perl pl pm
|
||||
application/x-pkcs12 p12 pfx
|
||||
application/x-pkcs7-certificates p7b spc
|
||||
application/x-pkcs7-certreqresp p7r
|
||||
application/x-rar-compressed rar
|
||||
application/x-redhat-package-manager rpm
|
||||
application/x-research-info-systems ris
|
||||
application/x-sea sea
|
||||
application/x-sh sh
|
||||
application/x-shar shar
|
||||
application/x-shockwave-flash swf
|
||||
application/x-silverlight-app xap
|
||||
application/x-sql sql
|
||||
application/x-stuffit sit
|
||||
application/x-stuffitx sitx
|
||||
application/x-subrip srt
|
||||
application/x-sv4cpio sv4cpio
|
||||
application/x-sv4crc sv4crc
|
||||
application/x-t3vm-image t3
|
||||
application/x-tads gam
|
||||
application/x-tar tar
|
||||
application/x-tcl tcl tk
|
||||
application/x-tex tex
|
||||
application/x-tex-tfm tfm
|
||||
application/x-texinfo texinfo texi
|
||||
application/x-tgif obj
|
||||
application/x-ustar ustar
|
||||
application/x-virtualbox-hdd hdd
|
||||
application/x-virtualbox-ova ova
|
||||
application/x-virtualbox-ovf ovf
|
||||
application/x-virtualbox-vbox vbox
|
||||
application/x-virtualbox-vbox-extpack vbox-extpack
|
||||
application/x-virtualbox-vdi vdi
|
||||
application/x-virtualbox-vhd vhd
|
||||
application/x-virtualbox-vmdk vmdk
|
||||
application/x-wais-source src
|
||||
application/x-web-app-manifest+json webapp
|
||||
application/x-x509-ca-cert der crt pem
|
||||
application/x-xfig fig
|
||||
application/x-xliff+xml xlf
|
||||
application/x-xpinstall xpi
|
||||
application/x-xz xz
|
||||
application/x-zmachine z1 z2 z3 z4 z5 z6 z7 z8
|
||||
application/xaml+xml xaml
|
||||
application/xcap-diff+xml xdf
|
||||
application/xenc+xml xenc
|
||||
application/xhtml+xml xhtml xht
|
||||
application/xml xml xsl xsd rng
|
||||
application/xml-dtd dtd
|
||||
application/xop+xml xop
|
||||
application/xproc+xml xpl
|
||||
application/xslt+xml xslt
|
||||
application/xspf+xml xspf
|
||||
application/xv+xml mxml xhvml xvml xvm
|
||||
application/yang yang
|
||||
application/yin+xml yin
|
||||
application/zip zip
|
||||
audio/3gpp 3gpp
|
||||
audio/adpcm adp
|
||||
audio/basic au snd
|
||||
audio/midi mid midi kar rmi
|
||||
audio/mp3 mp3
|
||||
audio/mp4 m4a mp4a
|
||||
audio/mpeg mpga mp2 mp2a m2a m3a
|
||||
audio/ogg oga ogg spx
|
||||
audio/s3m s3m
|
||||
audio/silk sil
|
||||
audio/vnd.dece.audio uva uvva
|
||||
audio/vnd.digital-winds eol
|
||||
audio/vnd.dra dra
|
||||
audio/vnd.dts dts
|
||||
audio/vnd.dts.hd dtshd
|
||||
audio/vnd.lucent.voice lvp
|
||||
audio/vnd.ms-playready.media.pya pya
|
||||
audio/vnd.nuera.ecelp4800 ecelp4800
|
||||
audio/vnd.nuera.ecelp7470 ecelp7470
|
||||
audio/vnd.nuera.ecelp9600 ecelp9600
|
||||
audio/vnd.rip rip
|
||||
audio/wav wav
|
||||
audio/webm weba
|
||||
audio/x-aac aac
|
||||
audio/x-aiff aif aiff aifc
|
||||
audio/x-caf caf
|
||||
audio/x-flac flac
|
||||
audio/x-matroska mka
|
||||
audio/x-mpegurl m3u
|
||||
audio/x-ms-wax wax
|
||||
audio/x-ms-wma wma
|
||||
audio/x-pn-realaudio ram ra
|
||||
audio/x-pn-realaudio-plugin rmp
|
||||
audio/xm xm
|
||||
chemical/x-cdx cdx
|
||||
chemical/x-cif cif
|
||||
chemical/x-cmdf cmdf
|
||||
chemical/x-cml cml
|
||||
chemical/x-csml csml
|
||||
chemical/x-xyz xyz
|
||||
font/collection ttc
|
||||
font/otf otf
|
||||
font/ttf ttf
|
||||
font/woff woff
|
||||
font/woff2 woff2
|
||||
image/aces exr
|
||||
image/apng apng
|
||||
image/bmp bmp
|
||||
image/cgm cgm
|
||||
image/dicom-rle drle
|
||||
image/fits fits
|
||||
image/g3fax g3
|
||||
image/gif gif
|
||||
image/heic heic
|
||||
image/heic-sequence heics
|
||||
image/heif heif
|
||||
image/heif-sequence heifs
|
||||
image/ief ief
|
||||
image/jls jls
|
||||
image/jp2 jp2 jpg2
|
||||
image/jpeg jpeg jpg jpe
|
||||
image/jpm jpm
|
||||
image/jpx jpx jpf
|
||||
image/jxr jxr
|
||||
image/ktx ktx
|
||||
image/png png
|
||||
image/prs.btif btif
|
||||
image/prs.pti pti
|
||||
image/sgi sgi
|
||||
image/svg+xml svg svgz
|
||||
image/t38 t38
|
||||
image/tiff tif tiff
|
||||
image/tiff-fx tfx
|
||||
image/vnd.adobe.photoshop psd
|
||||
image/vnd.airzip.accelerator.azv azv
|
||||
image/vnd.dece.graphic uvi uvvi uvg uvvg
|
||||
image/vnd.djvu djvu djv
|
||||
image/vnd.dvb.subtitle sub
|
||||
image/vnd.dwg dwg
|
||||
image/vnd.dxf dxf
|
||||
image/vnd.fastbidsheet fbs
|
||||
image/vnd.fpx fpx
|
||||
image/vnd.fst fst
|
||||
image/vnd.fujixerox.edmics-mmr mmr
|
||||
image/vnd.fujixerox.edmics-rlc rlc
|
||||
image/vnd.microsoft.icon ico
|
||||
image/vnd.ms-modi mdi
|
||||
image/vnd.ms-photo wdp
|
||||
image/vnd.net-fpx npx
|
||||
image/vnd.tencent.tap tap
|
||||
image/vnd.valve.source.texture vtf
|
||||
image/vnd.wap.wbmp wbmp
|
||||
image/vnd.xiff xif
|
||||
image/vnd.zbrush.pcx pcx
|
||||
image/webp webp
|
||||
image/x-3ds 3ds
|
||||
image/x-cmu-raster ras
|
||||
image/x-cmx cmx
|
||||
image/x-freehand fh fhc fh4 fh5 fh7
|
||||
image/x-jng jng
|
||||
image/x-mrsid-image sid
|
||||
image/x-pict pic pct
|
||||
image/x-portable-anymap pnm
|
||||
image/x-portable-bitmap pbm
|
||||
image/x-portable-graymap pgm
|
||||
image/x-portable-pixmap ppm
|
||||
image/x-rgb rgb
|
||||
image/x-tga tga
|
||||
image/x-xbitmap xbm
|
||||
image/x-xpixmap xpm
|
||||
image/x-xwindowdump xwd
|
||||
message/disposition-notification disposition-notification
|
||||
message/global u8msg
|
||||
message/global-delivery-status u8dsn
|
||||
message/global-disposition-notification u8mdn
|
||||
message/global-headers u8hdr
|
||||
message/rfc822 eml mime
|
||||
message/vnd.wfa.wsc wsc
|
||||
model/3mf 3mf
|
||||
model/gltf+json gltf
|
||||
model/gltf-binary glb
|
||||
model/iges igs iges
|
||||
model/mesh msh mesh silo
|
||||
model/vnd.collada+xml dae
|
||||
model/vnd.dwf dwf
|
||||
model/vnd.gdl gdl
|
||||
model/vnd.gtw gtw
|
||||
model/vnd.mts mts
|
||||
model/vnd.opengex ogex
|
||||
model/vnd.parasolid.transmit.binary x_b
|
||||
model/vnd.parasolid.transmit.text x_t
|
||||
model/vnd.usdz+zip usdz
|
||||
model/vnd.valve.source.compiled-map bsp
|
||||
model/vnd.vtu vtu
|
||||
model/vrml wrl vrml
|
||||
model/x3d+binary x3db x3dbz
|
||||
model/x3d+vrml x3dv x3dvz
|
||||
model/x3d+xml x3d x3dz
|
||||
text/cache-manifest appcache manifest
|
||||
text/calendar ics ifb
|
||||
text/coffeescript coffee litcoffee
|
||||
text/css css
|
||||
text/csv csv
|
||||
text/html html htm shtml
|
||||
text/jade jade
|
||||
text/jsx jsx
|
||||
text/less less
|
||||
text/markdown markdown md
|
||||
text/mathml mml
|
||||
text/mdx mdx
|
||||
text/n3 n3
|
||||
text/plain txt text conf def list log in ini
|
||||
text/prs.lines.tag dsc
|
||||
text/richtext rtx
|
||||
text/sgml sgml sgm
|
||||
text/shex shex
|
||||
text/slim slim slm
|
||||
text/stylus stylus styl
|
||||
text/tab-separated-values tsv
|
||||
text/troff t tr roff man me ms
|
||||
text/turtle ttl
|
||||
text/uri-list uri uris urls
|
||||
text/vcard vcard
|
||||
text/vnd.curl curl
|
||||
text/vnd.curl.dcurl dcurl
|
||||
text/vnd.curl.mcurl mcurl
|
||||
text/vnd.curl.scurl scurl
|
||||
text/vnd.fly fly
|
||||
text/vnd.fmi.flexstor flx
|
||||
text/vnd.graphviz gv
|
||||
text/vnd.in3d.3dml 3dml
|
||||
text/vnd.in3d.spot spot
|
||||
text/vnd.sun.j2me.app-descriptor jad
|
||||
text/vnd.wap.wml wml
|
||||
text/vnd.wap.wmlscript wmls
|
||||
text/vtt vtt
|
||||
text/x-asm s asm
|
||||
text/x-c c cc cxx cpp h hh dic
|
||||
text/x-component htc
|
||||
text/x-fortran f for f77 f90
|
||||
text/x-handlebars-template hbs
|
||||
text/x-java-source java
|
||||
text/x-lua lua
|
||||
text/x-markdown mkd
|
||||
text/x-nfo nfo
|
||||
text/x-opml opml
|
||||
text/x-pascal p pas
|
||||
text/x-processing pde
|
||||
text/x-sass sass
|
||||
text/x-scss scss
|
||||
text/x-setext etx
|
||||
text/x-sfv sfv
|
||||
text/x-suse-ymp ymp
|
||||
text/x-uuencode uu
|
||||
text/x-vcalendar vcs
|
||||
text/x-vcard vcf
|
||||
text/yaml yaml yml
|
||||
video/3gpp 3gp
|
||||
video/3gpp2 3g2
|
||||
video/h261 h261
|
||||
video/h263 h263
|
||||
video/h264 h264
|
||||
video/jpeg jpgv
|
||||
video/jpm jpgm
|
||||
video/mj2 mj2 mjp2
|
||||
video/mp2t ts
|
||||
video/mp4 mp4 mp4v mpg4
|
||||
video/mpeg mpeg mpg mpe m1v m2v
|
||||
video/ogg ogv
|
||||
video/quicktime qt mov
|
||||
video/vnd.dece.hd uvh uvvh
|
||||
video/vnd.dece.mobile uvm uvvm
|
||||
video/vnd.dece.pd uvp uvvp
|
||||
video/vnd.dece.sd uvs uvvs
|
||||
video/vnd.dece.video uvv uvvv
|
||||
video/vnd.dvb.file dvb
|
||||
video/vnd.fvt fvt
|
||||
video/vnd.mpegurl mxu m4u
|
||||
video/vnd.ms-playready.media.pyv pyv
|
||||
video/vnd.uvvu.mp4 uvu uvvu
|
||||
video/vnd.vivo viv
|
||||
video/webm webm
|
||||
video/x-f4v f4v
|
||||
video/x-fli fli
|
||||
video/x-flv flv
|
||||
video/x-m4v m4v
|
||||
video/x-matroska mkv mk3d mks
|
||||
video/x-mng mng
|
||||
video/x-ms-asf asf asx
|
||||
video/x-ms-vob vob
|
||||
video/x-ms-wm wm
|
||||
video/x-ms-wmv wmv
|
||||
video/x-ms-wmx wmx
|
||||
video/x-ms-wvx wvx
|
||||
video/x-msvideo avi
|
||||
video/x-sgi-movie movie
|
||||
video/x-smv smv
|
||||
x-conference/x-cooltalk ice
|
||||
217
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/page.rb
vendored
Normal file
217
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/page.rb
vendored
Normal file
@@ -0,0 +1,217 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Jekyll
|
||||
class Page
|
||||
include Convertible
|
||||
|
||||
attr_writer :dir
|
||||
attr_accessor :site, :pager
|
||||
attr_accessor :name, :ext, :basename
|
||||
attr_accessor :data, :content, :output
|
||||
|
||||
alias_method :extname, :ext
|
||||
|
||||
# Attributes for Liquid templates
|
||||
ATTRIBUTES_FOR_LIQUID = %w(
|
||||
content
|
||||
dir
|
||||
excerpt
|
||||
name
|
||||
path
|
||||
url
|
||||
).freeze
|
||||
|
||||
# A set of extensions that are considered HTML or HTML-like so we
|
||||
# should not alter them, this includes .xhtml through XHTM5.
|
||||
|
||||
HTML_EXTENSIONS = %w(
|
||||
.html
|
||||
.xhtml
|
||||
.htm
|
||||
).freeze
|
||||
|
||||
# Initialize a new Page.
|
||||
#
|
||||
# site - The Site object.
|
||||
# base - The String path to the source.
|
||||
# dir - The String path between the source and the file.
|
||||
# name - The String filename of the file.
|
||||
def initialize(site, base, dir, name)
|
||||
@site = site
|
||||
@base = base
|
||||
@dir = dir
|
||||
@name = name
|
||||
@path = if site.in_theme_dir(base) == base # we're in a theme
|
||||
site.in_theme_dir(base, dir, name)
|
||||
else
|
||||
site.in_source_dir(base, dir, name)
|
||||
end
|
||||
|
||||
process(name)
|
||||
read_yaml(PathManager.join(base, dir), name)
|
||||
generate_excerpt if site.config["page_excerpts"]
|
||||
|
||||
data.default_proc = proc do |_, key|
|
||||
site.frontmatter_defaults.find(relative_path, type, key)
|
||||
end
|
||||
|
||||
Jekyll::Hooks.trigger :pages, :post_init, self
|
||||
end
|
||||
|
||||
# The generated directory into which the page will be placed
|
||||
# upon generation. This is derived from the permalink or, if
|
||||
# permalink is absent, will be '/'
|
||||
#
|
||||
# Returns the String destination directory.
|
||||
def dir
|
||||
url.end_with?("/") ? url : url_dir
|
||||
end
|
||||
|
||||
# The full path and filename of the post. Defined in the YAML of the post
|
||||
# body.
|
||||
#
|
||||
# Returns the String permalink or nil if none has been set.
|
||||
def permalink
|
||||
data.nil? ? nil : data["permalink"]
|
||||
end
|
||||
|
||||
# The template of the permalink.
|
||||
#
|
||||
# Returns the template String.
|
||||
def template
|
||||
if !html?
|
||||
"/:path/:basename:output_ext"
|
||||
elsif index?
|
||||
"/:path/"
|
||||
else
|
||||
Utils.add_permalink_suffix("/:path/:basename", site.permalink_style)
|
||||
end
|
||||
end
|
||||
|
||||
# The generated relative url of this page. e.g. /about.html.
|
||||
#
|
||||
# Returns the String url.
|
||||
def url
|
||||
@url ||= URL.new(
|
||||
:template => template,
|
||||
:placeholders => url_placeholders,
|
||||
:permalink => permalink
|
||||
).to_s
|
||||
end
|
||||
|
||||
# Returns a hash of URL placeholder names (as symbols) mapping to the
|
||||
# desired placeholder replacements. For details see "url.rb"
|
||||
def url_placeholders
|
||||
{
|
||||
:path => @dir,
|
||||
:basename => basename,
|
||||
:output_ext => output_ext,
|
||||
}
|
||||
end
|
||||
|
||||
# Extract information from the page filename.
|
||||
#
|
||||
# name - The String filename of the page file.
|
||||
#
|
||||
# NOTE: `String#gsub` removes all trailing periods (in comparison to `String#chomp`)
|
||||
# Returns nothing.
|
||||
def process(name)
|
||||
return unless name
|
||||
|
||||
self.ext = File.extname(name)
|
||||
self.basename = name[0..-ext.length - 1].gsub(%r!\.*\z!, "")
|
||||
end
|
||||
|
||||
# Add any necessary layouts to this post
|
||||
#
|
||||
# layouts - The Hash of {"name" => "layout"}.
|
||||
# site_payload - The site payload Hash.
|
||||
#
|
||||
# Returns String rendered page.
|
||||
def render(layouts, site_payload)
|
||||
site_payload["page"] = to_liquid
|
||||
site_payload["paginator"] = pager.to_liquid
|
||||
|
||||
do_layout(site_payload, layouts)
|
||||
end
|
||||
|
||||
# The path to the source file
|
||||
#
|
||||
# Returns the path to the source file
|
||||
def path
|
||||
data.fetch("path") { relative_path }
|
||||
end
|
||||
|
||||
# The path to the page source file, relative to the site source
|
||||
def relative_path
|
||||
@relative_path ||= PathManager.join(@dir, @name).sub(%r!\A/!, "")
|
||||
end
|
||||
|
||||
# Obtain destination path.
|
||||
#
|
||||
# dest - The String path to the destination dir.
|
||||
#
|
||||
# Returns the destination file path String.
|
||||
def destination(dest)
|
||||
@destination ||= {}
|
||||
@destination[dest] ||= begin
|
||||
path = site.in_dest_dir(dest, URL.unescape_path(url))
|
||||
path = File.join(path, "index") if url.end_with?("/")
|
||||
path << output_ext unless path.end_with? output_ext
|
||||
path
|
||||
end
|
||||
end
|
||||
|
||||
# Returns the object as a debug String.
|
||||
def inspect
|
||||
"#<#{self.class} @relative_path=#{relative_path.inspect}>"
|
||||
end
|
||||
|
||||
# Returns the Boolean of whether this Page is HTML or not.
|
||||
def html?
|
||||
HTML_EXTENSIONS.include?(output_ext)
|
||||
end
|
||||
|
||||
# Returns the Boolean of whether this Page is an index file or not.
|
||||
def index?
|
||||
basename == "index"
|
||||
end
|
||||
|
||||
def trigger_hooks(hook_name, *args)
|
||||
Jekyll::Hooks.trigger :pages, hook_name, self, *args
|
||||
end
|
||||
|
||||
def write?
|
||||
true
|
||||
end
|
||||
|
||||
def excerpt_separator
|
||||
@excerpt_separator ||= (data["excerpt_separator"] || site.config["excerpt_separator"]).to_s
|
||||
end
|
||||
|
||||
def excerpt
|
||||
return @excerpt if defined?(@excerpt)
|
||||
|
||||
@excerpt = data["excerpt"] ? data["excerpt"].to_s : nil
|
||||
end
|
||||
|
||||
def generate_excerpt?
|
||||
!excerpt_separator.empty? && instance_of?(Jekyll::Page) && html?
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def generate_excerpt
|
||||
return unless generate_excerpt?
|
||||
|
||||
data["excerpt"] ||= Jekyll::PageExcerpt.new(self)
|
||||
end
|
||||
|
||||
def url_dir
|
||||
@url_dir ||= begin
|
||||
value = File.dirname(url)
|
||||
value.end_with?("/") ? value : "#{value}/"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
25
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/page_excerpt.rb
vendored
Normal file
25
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/page_excerpt.rb
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Jekyll
|
||||
class PageExcerpt < Excerpt
|
||||
attr_reader :doc
|
||||
alias_method :id, :relative_path
|
||||
|
||||
EXCERPT_ATTRIBUTES = (Page::ATTRIBUTES_FOR_LIQUID - %w(excerpt)).freeze
|
||||
private_constant :EXCERPT_ATTRIBUTES
|
||||
|
||||
def to_liquid
|
||||
@to_liquid ||= doc.to_liquid(EXCERPT_ATTRIBUTES)
|
||||
end
|
||||
|
||||
def render_with_liquid?
|
||||
return false if data["render_with_liquid"] == false
|
||||
|
||||
Jekyll::Utils.has_liquid_construct?(content)
|
||||
end
|
||||
|
||||
def inspect
|
||||
"#<#{self.class} id=#{id.inspect}>"
|
||||
end
|
||||
end
|
||||
end
|
||||
14
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/page_without_a_file.rb
vendored
Normal file
14
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/page_without_a_file.rb
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Jekyll
|
||||
# A Jekyll::Page subclass to handle processing files without reading it to
|
||||
# determine the page-data and page-content based on Front Matter delimiters.
|
||||
#
|
||||
# The class instance is basically just a bare-bones entity with just
|
||||
# attributes "dir", "name", "path", "url" defined on it.
|
||||
class PageWithoutAFile < Page
|
||||
def read_yaml(*)
|
||||
@data ||= {}
|
||||
end
|
||||
end
|
||||
end
|
||||
74
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/path_manager.rb
vendored
Normal file
74
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/path_manager.rb
vendored
Normal file
@@ -0,0 +1,74 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Jekyll
|
||||
# A singleton class that caches frozen instances of path strings returned from its methods.
|
||||
#
|
||||
# NOTE:
|
||||
# This class exists because `File.join` allocates an Array and returns a new String on every
|
||||
# call using **the same arguments**. Caching the result means reduced memory usage.
|
||||
# However, the caches are never flushed so that they can be used even when a site is
|
||||
# regenerating. The results are frozen to deter mutation of the cached string.
|
||||
#
|
||||
# Therefore, employ this class only for situations where caching the result is necessary
|
||||
# for performance reasons.
|
||||
#
|
||||
class PathManager
|
||||
# This class cannot be initialized from outside
|
||||
private_class_method :new
|
||||
|
||||
class << self
|
||||
# Wraps `File.join` to cache the frozen result.
|
||||
# Reassigns `nil`, empty strings and empty arrays to a frozen empty string beforehand.
|
||||
#
|
||||
# Returns a frozen string.
|
||||
def join(base, item)
|
||||
base = "" if base.nil? || base.empty?
|
||||
item = "" if item.nil? || item.empty?
|
||||
@join ||= {}
|
||||
@join[base] ||= {}
|
||||
@join[base][item] ||= File.join(base, item).freeze
|
||||
end
|
||||
|
||||
# Ensures the questionable path is prefixed with the base directory
|
||||
# and prepends the questionable path with the base directory if false.
|
||||
#
|
||||
# Returns a frozen string.
|
||||
def sanitized_path(base_directory, questionable_path)
|
||||
@sanitized_path ||= {}
|
||||
@sanitized_path[base_directory] ||= {}
|
||||
@sanitized_path[base_directory][questionable_path] ||= begin
|
||||
if questionable_path.nil?
|
||||
base_directory.freeze
|
||||
else
|
||||
sanitize_and_join(base_directory, questionable_path).freeze
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def sanitize_and_join(base_directory, questionable_path)
|
||||
clean_path = if questionable_path.start_with?("~")
|
||||
questionable_path.dup.insert(0, "/")
|
||||
else
|
||||
questionable_path
|
||||
end
|
||||
clean_path = File.expand_path(clean_path, "/")
|
||||
return clean_path if clean_path.eql?(base_directory)
|
||||
|
||||
# remove any remaining extra leading slashes not stripped away by calling
|
||||
# `File.expand_path` above.
|
||||
clean_path.squeeze!("/")
|
||||
return clean_path if clean_path.start_with?(slashed_dir_cache(base_directory))
|
||||
|
||||
clean_path.sub!(%r!\A\w:/!, "/")
|
||||
join(base_directory, clean_path)
|
||||
end
|
||||
|
||||
def slashed_dir_cache(base_directory)
|
||||
@slashed_dir_cache ||= {}
|
||||
@slashed_dir_cache[base_directory] ||= base_directory.sub(%r!\z!, "/")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
92
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/plugin.rb
vendored
Normal file
92
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/plugin.rb
vendored
Normal file
@@ -0,0 +1,92 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Jekyll
|
||||
class Plugin
|
||||
PRIORITIES = {
|
||||
:low => -10,
|
||||
:highest => 100,
|
||||
:lowest => -100,
|
||||
:normal => 0,
|
||||
:high => 10,
|
||||
}.freeze
|
||||
|
||||
#
|
||||
|
||||
def self.inherited(const)
|
||||
catch_inheritance(const) do |const_|
|
||||
catch_inheritance(const_)
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
|
||||
def self.catch_inheritance(const)
|
||||
const.define_singleton_method :inherited do |const_|
|
||||
(@children ||= Set.new).add const_
|
||||
yield const_ if block_given?
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
|
||||
def self.descendants
|
||||
@children ||= Set.new
|
||||
out = @children.map(&:descendants)
|
||||
out << self unless superclass == Plugin
|
||||
Set.new(out).flatten
|
||||
end
|
||||
|
||||
# Get or set the priority of this plugin. When called without an
|
||||
# argument it returns the priority. When an argument is given, it will
|
||||
# set the priority.
|
||||
#
|
||||
# priority - The Symbol priority (default: nil). Valid options are:
|
||||
# :lowest, :low, :normal, :high, :highest
|
||||
#
|
||||
# Returns the Symbol priority.
|
||||
def self.priority(priority = nil)
|
||||
@priority ||= nil
|
||||
@priority = priority if priority && PRIORITIES.key?(priority)
|
||||
@priority || :normal
|
||||
end
|
||||
|
||||
# Get or set the safety of this plugin. When called without an argument
|
||||
# it returns the safety. When an argument is given, it will set the
|
||||
# safety.
|
||||
#
|
||||
# safe - The Boolean safety (default: nil).
|
||||
#
|
||||
# Returns the safety Boolean.
|
||||
def self.safe(safe = nil)
|
||||
@safe = safe unless defined?(@safe) && safe.nil?
|
||||
@safe || false
|
||||
end
|
||||
|
||||
# Spaceship is priority [higher -> lower]
|
||||
#
|
||||
# other - The class to be compared.
|
||||
#
|
||||
# Returns -1, 0, 1.
|
||||
def self.<=>(other)
|
||||
PRIORITIES[other.priority] <=> PRIORITIES[priority]
|
||||
end
|
||||
|
||||
# Spaceship is priority [higher -> lower]
|
||||
#
|
||||
# other - The class to be compared.
|
||||
#
|
||||
# Returns -1, 0, 1.
|
||||
def <=>(other)
|
||||
self.class <=> other.class
|
||||
end
|
||||
|
||||
# Initialize a new plugin. This should be overridden by the subclass.
|
||||
#
|
||||
# config - The Hash of configuration options.
|
||||
#
|
||||
# Returns a new instance.
|
||||
def initialize(config = {})
|
||||
# no-op for default
|
||||
end
|
||||
end
|
||||
end
|
||||
115
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/plugin_manager.rb
vendored
Normal file
115
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/plugin_manager.rb
vendored
Normal file
@@ -0,0 +1,115 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Jekyll
|
||||
class PluginManager
|
||||
attr_reader :site
|
||||
|
||||
# Create an instance of this class.
|
||||
#
|
||||
# site - the instance of Jekyll::Site we're concerned with
|
||||
#
|
||||
# Returns nothing
|
||||
def initialize(site)
|
||||
@site = site
|
||||
end
|
||||
|
||||
# Require all the plugins which are allowed.
|
||||
#
|
||||
# Returns nothing
|
||||
def conscientious_require
|
||||
require_theme_deps if site.theme
|
||||
require_plugin_files
|
||||
require_gems
|
||||
deprecation_checks
|
||||
end
|
||||
|
||||
# Require each of the gem plugins specified.
|
||||
#
|
||||
# Returns nothing.
|
||||
def require_gems
|
||||
Jekyll::External.require_with_graceful_fail(
|
||||
site.gems.select { |plugin| plugin_allowed?(plugin) }
|
||||
)
|
||||
end
|
||||
|
||||
# Require each of the runtime_dependencies specified by the theme's gemspec.
|
||||
#
|
||||
# Returns false only if no dependencies have been specified, otherwise nothing.
|
||||
def require_theme_deps
|
||||
return false unless site.theme.runtime_dependencies
|
||||
|
||||
site.theme.runtime_dependencies.each do |dep|
|
||||
next if dep.name == "jekyll"
|
||||
|
||||
External.require_with_graceful_fail(dep.name) if plugin_allowed?(dep.name)
|
||||
end
|
||||
end
|
||||
|
||||
def self.require_from_bundler
|
||||
if !ENV["JEKYLL_NO_BUNDLER_REQUIRE"] && File.file?("Gemfile")
|
||||
require "bundler"
|
||||
|
||||
Bundler.setup
|
||||
required_gems = Bundler.require(:jekyll_plugins)
|
||||
message = "Required #{required_gems.map(&:name).join(", ")}"
|
||||
Jekyll.logger.debug("PluginManager:", message)
|
||||
ENV["JEKYLL_NO_BUNDLER_REQUIRE"] = "true"
|
||||
|
||||
true
|
||||
else
|
||||
false
|
||||
end
|
||||
end
|
||||
|
||||
# Check whether a gem plugin is allowed to be used during this build.
|
||||
#
|
||||
# plugin_name - the name of the plugin
|
||||
#
|
||||
# Returns true if the plugin name is in the whitelist or if the site is not
|
||||
# in safe mode.
|
||||
def plugin_allowed?(plugin_name)
|
||||
!site.safe || whitelist.include?(plugin_name)
|
||||
end
|
||||
|
||||
# Build an array of allowed plugin gem names.
|
||||
#
|
||||
# Returns an array of strings, each string being the name of a gem name
|
||||
# that is allowed to be used.
|
||||
def whitelist
|
||||
@whitelist ||= Array[site.config["whitelist"]].flatten
|
||||
end
|
||||
|
||||
# Require all .rb files if safe mode is off
|
||||
#
|
||||
# Returns nothing.
|
||||
def require_plugin_files
|
||||
unless site.safe
|
||||
plugins_path.each do |plugin_search_path|
|
||||
plugin_files = Utils.safe_glob(plugin_search_path, File.join("**", "*.rb"))
|
||||
Jekyll::External.require_with_graceful_fail(plugin_files)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Public: Setup the plugin search path
|
||||
#
|
||||
# Returns an Array of plugin search paths
|
||||
def plugins_path
|
||||
if site.config["plugins_dir"].eql? Jekyll::Configuration::DEFAULTS["plugins_dir"]
|
||||
[site.in_source_dir(site.config["plugins_dir"])]
|
||||
else
|
||||
Array(site.config["plugins_dir"]).map { |d| File.expand_path(d) }
|
||||
end
|
||||
end
|
||||
|
||||
def deprecation_checks
|
||||
pagination_included = (site.config["plugins"] || []).include?("jekyll-paginate") ||
|
||||
defined?(Jekyll::Paginate)
|
||||
if site.config["paginate"] && !pagination_included
|
||||
Jekyll::Deprecator.deprecation_message "You appear to have pagination " \
|
||||
"turned on, but you haven't included the `jekyll-paginate` gem. " \
|
||||
"Ensure you have `plugins: [jekyll-paginate]` in your configuration file."
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
58
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/profiler.rb
vendored
Normal file
58
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/profiler.rb
vendored
Normal file
@@ -0,0 +1,58 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Jekyll
|
||||
class Profiler
|
||||
TERMINAL_TABLE_STYLES = {
|
||||
:alignment => :right,
|
||||
:border_top => false,
|
||||
:border_bottom => false,
|
||||
}.freeze
|
||||
private_constant :TERMINAL_TABLE_STYLES
|
||||
|
||||
def self.tabulate(table_rows)
|
||||
require "terminal-table"
|
||||
|
||||
rows = table_rows.dup
|
||||
header = rows.shift
|
||||
footer = rows.pop
|
||||
output = +"\n"
|
||||
|
||||
table = Terminal::Table.new do |t|
|
||||
t << header
|
||||
t << :separator
|
||||
rows.each { |row| t << row }
|
||||
t << :separator
|
||||
t << footer
|
||||
t.style = TERMINAL_TABLE_STYLES
|
||||
t.align_column(0, :left)
|
||||
end
|
||||
|
||||
output << table.to_s << "\n"
|
||||
end
|
||||
|
||||
def initialize(site)
|
||||
@site = site
|
||||
end
|
||||
|
||||
def profile_process
|
||||
profile_data = { "PHASE" => "TIME" }
|
||||
total_time = 0
|
||||
|
||||
[:reset, :read, :generate, :render, :cleanup, :write].each do |method|
|
||||
start_time = Time.now
|
||||
@site.send(method)
|
||||
end_time = (Time.now - start_time).round(4)
|
||||
profile_data[method.to_s.upcase] = format("%.4f", end_time)
|
||||
total_time += end_time
|
||||
end
|
||||
|
||||
profile_data["TOTAL TIME"] = format("%.4f", total_time)
|
||||
|
||||
Jekyll.logger.info "\nBuild Process Summary:"
|
||||
Jekyll.logger.info Profiler.tabulate(Array(profile_data))
|
||||
|
||||
Jekyll.logger.info "\nSite Render Stats:"
|
||||
@site.print_stats
|
||||
end
|
||||
end
|
||||
end
|
||||
23
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/publisher.rb
vendored
Normal file
23
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/publisher.rb
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Jekyll
|
||||
class Publisher
|
||||
def initialize(site)
|
||||
@site = site
|
||||
end
|
||||
|
||||
def publish?(thing)
|
||||
can_be_published?(thing) && !hidden_in_the_future?(thing)
|
||||
end
|
||||
|
||||
def hidden_in_the_future?(thing)
|
||||
thing.respond_to?(:date) && !@site.future && thing.date.to_i > @site.time.to_i
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def can_be_published?(thing)
|
||||
thing.data.fetch("published", true) || @site.unpublished
|
||||
end
|
||||
end
|
||||
end
|
||||
192
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/reader.rb
vendored
Normal file
192
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/reader.rb
vendored
Normal file
@@ -0,0 +1,192 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Jekyll
|
||||
class Reader
|
||||
attr_reader :site
|
||||
|
||||
def initialize(site)
|
||||
@site = site
|
||||
end
|
||||
|
||||
# Read Site data from disk and load it into internal data structures.
|
||||
#
|
||||
# Returns nothing.
|
||||
def read
|
||||
@site.layouts = LayoutReader.new(site).read
|
||||
read_directories
|
||||
read_included_excludes
|
||||
sort_files!
|
||||
@site.data = DataReader.new(site).read(site.config["data_dir"])
|
||||
CollectionReader.new(site).read
|
||||
ThemeAssetsReader.new(site).read
|
||||
end
|
||||
|
||||
# Sorts posts, pages, and static files.
|
||||
def sort_files!
|
||||
site.collections.each_value { |c| c.docs.sort! }
|
||||
site.pages.sort_by!(&:name)
|
||||
site.static_files.sort_by!(&:relative_path)
|
||||
end
|
||||
|
||||
# Recursively traverse directories to find pages and static files
|
||||
# that will become part of the site according to the rules in
|
||||
# filter_entries.
|
||||
#
|
||||
# dir - The String relative path of the directory to read. Default: ''.
|
||||
#
|
||||
# Returns nothing.
|
||||
def read_directories(dir = "")
|
||||
base = site.in_source_dir(dir)
|
||||
|
||||
return unless File.directory?(base)
|
||||
|
||||
dot_dirs = []
|
||||
dot_pages = []
|
||||
dot_static_files = []
|
||||
|
||||
dot = Dir.chdir(base) { filter_entries(Dir.entries("."), base) }
|
||||
dot.each do |entry|
|
||||
file_path = @site.in_source_dir(base, entry)
|
||||
if File.directory?(file_path)
|
||||
dot_dirs << entry
|
||||
elsif Utils.has_yaml_header?(file_path)
|
||||
dot_pages << entry
|
||||
else
|
||||
dot_static_files << entry
|
||||
end
|
||||
end
|
||||
|
||||
retrieve_posts(dir)
|
||||
retrieve_dirs(base, dir, dot_dirs)
|
||||
retrieve_pages(dir, dot_pages)
|
||||
retrieve_static_files(dir, dot_static_files)
|
||||
end
|
||||
|
||||
# Retrieves all the posts(posts/drafts) from the given directory
|
||||
# and add them to the site and sort them.
|
||||
#
|
||||
# dir - The String representing the directory to retrieve the posts from.
|
||||
#
|
||||
# Returns nothing.
|
||||
def retrieve_posts(dir)
|
||||
return if outside_configured_directory?(dir)
|
||||
|
||||
site.posts.docs.concat(post_reader.read_posts(dir))
|
||||
site.posts.docs.concat(post_reader.read_drafts(dir)) if site.show_drafts
|
||||
end
|
||||
|
||||
# Recursively traverse directories with the read_directories function.
|
||||
#
|
||||
# base - The String representing the site's base directory.
|
||||
# dir - The String representing the directory to traverse down.
|
||||
# dot_dirs - The Array of subdirectories in the dir.
|
||||
#
|
||||
# Returns nothing.
|
||||
def retrieve_dirs(_base, dir, dot_dirs)
|
||||
dot_dirs.each do |file|
|
||||
dir_path = site.in_source_dir(dir, file)
|
||||
rel_path = PathManager.join(dir, file)
|
||||
@site.reader.read_directories(rel_path) unless @site.dest.chomp("/") == dir_path
|
||||
end
|
||||
end
|
||||
|
||||
# Retrieve all the pages from the current directory,
|
||||
# add them to the site and sort them.
|
||||
#
|
||||
# dir - The String representing the directory retrieve the pages from.
|
||||
# dot_pages - The Array of pages in the dir.
|
||||
#
|
||||
# Returns nothing.
|
||||
def retrieve_pages(dir, dot_pages)
|
||||
site.pages.concat(PageReader.new(site, dir).read(dot_pages))
|
||||
end
|
||||
|
||||
# Retrieve all the static files from the current directory,
|
||||
# add them to the site and sort them.
|
||||
#
|
||||
# dir - The directory retrieve the static files from.
|
||||
# dot_static_files - The static files in the dir.
|
||||
#
|
||||
# Returns nothing.
|
||||
def retrieve_static_files(dir, dot_static_files)
|
||||
site.static_files.concat(StaticFileReader.new(site, dir).read(dot_static_files))
|
||||
end
|
||||
|
||||
# Filter out any files/directories that are hidden or backup files (start
|
||||
# with "." or "#" or end with "~"), or contain site content (start with "_"),
|
||||
# or are excluded in the site configuration, unless they are web server
|
||||
# files such as '.htaccess'.
|
||||
#
|
||||
# entries - The Array of String file/directory entries to filter.
|
||||
# base_directory - The string representing the optional base directory.
|
||||
#
|
||||
# Returns the Array of filtered entries.
|
||||
def filter_entries(entries, base_directory = nil)
|
||||
EntryFilter.new(site, base_directory).filter(entries)
|
||||
end
|
||||
|
||||
# Read the entries from a particular directory for processing
|
||||
#
|
||||
# dir - The String representing the relative path of the directory to read.
|
||||
# subfolder - The String representing the directory to read.
|
||||
#
|
||||
# Returns the list of entries to process
|
||||
def get_entries(dir, subfolder)
|
||||
base = site.in_source_dir(dir, subfolder)
|
||||
return [] unless File.exist?(base)
|
||||
|
||||
entries = Dir.chdir(base) { filter_entries(Dir["**/*"], base) }
|
||||
entries.delete_if { |e| File.directory?(site.in_source_dir(base, e)) }
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# Internal
|
||||
#
|
||||
# Determine if the directory is supposed to contain posts and drafts.
|
||||
# If the user has defined a custom collections_dir, then attempt to read
|
||||
# posts and drafts only from within that directory.
|
||||
#
|
||||
# Returns true if a custom collections_dir has been set but current directory lies
|
||||
# outside that directory.
|
||||
def outside_configured_directory?(dir)
|
||||
collections_dir = site.config["collections_dir"]
|
||||
!collections_dir.empty? && !dir.start_with?("/#{collections_dir}")
|
||||
end
|
||||
|
||||
# Create a single PostReader instance to retrieve drafts and posts from all valid
|
||||
# directories in current site.
|
||||
def post_reader
|
||||
@post_reader ||= PostReader.new(site)
|
||||
end
|
||||
|
||||
def read_included_excludes
|
||||
entry_filter = EntryFilter.new(site)
|
||||
|
||||
site.include.each do |entry|
|
||||
entry_path = site.in_source_dir(entry)
|
||||
next if File.directory?(entry_path)
|
||||
next if entry_filter.symlink?(entry_path)
|
||||
|
||||
read_included_file(entry_path) if File.file?(entry_path)
|
||||
end
|
||||
end
|
||||
|
||||
def read_included_file(entry_path)
|
||||
if Utils.has_yaml_header?(entry_path)
|
||||
conditionally_generate_entry(entry_path, site.pages, PageReader)
|
||||
else
|
||||
conditionally_generate_entry(entry_path, site.static_files, StaticFileReader)
|
||||
end
|
||||
end
|
||||
|
||||
def conditionally_generate_entry(entry_path, container, reader)
|
||||
return if container.find { |item| site.in_source_dir(item.relative_path) == entry_path }
|
||||
|
||||
dir, files = File.split(entry_path)
|
||||
dir.sub!(site.source, "")
|
||||
files = Array(files)
|
||||
container.concat(reader.new(site, dir).read(files))
|
||||
end
|
||||
end
|
||||
end
|
||||
23
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/readers/collection_reader.rb
vendored
Normal file
23
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/readers/collection_reader.rb
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Jekyll
|
||||
class CollectionReader
|
||||
SPECIAL_COLLECTIONS = %w(posts data).freeze
|
||||
|
||||
attr_reader :site, :content
|
||||
|
||||
def initialize(site)
|
||||
@site = site
|
||||
@content = {}
|
||||
end
|
||||
|
||||
# Read in all collections specified in the configuration
|
||||
#
|
||||
# Returns nothing.
|
||||
def read
|
||||
site.collections.each_value do |collection|
|
||||
collection.read unless SPECIAL_COLLECTIONS.include?(collection.label)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
79
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/readers/data_reader.rb
vendored
Normal file
79
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/readers/data_reader.rb
vendored
Normal file
@@ -0,0 +1,79 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Jekyll
|
||||
class DataReader
|
||||
attr_reader :site, :content
|
||||
|
||||
def initialize(site)
|
||||
@site = site
|
||||
@content = {}
|
||||
@entry_filter = EntryFilter.new(site)
|
||||
@source_dir = site.in_source_dir("/")
|
||||
end
|
||||
|
||||
# Read all the files in <dir> and adds them to @content
|
||||
#
|
||||
# dir - The String relative path of the directory to read.
|
||||
#
|
||||
# Returns @content, a Hash of the .yaml, .yml,
|
||||
# .json, and .csv files in the base directory
|
||||
def read(dir)
|
||||
base = site.in_source_dir(dir)
|
||||
read_data_to(base, @content)
|
||||
@content
|
||||
end
|
||||
|
||||
# Read and parse all .yaml, .yml, .json, .csv and .tsv
|
||||
# files under <dir> and add them to the <data> variable.
|
||||
#
|
||||
# dir - The string absolute path of the directory to read.
|
||||
# data - The variable to which data will be added.
|
||||
#
|
||||
# Returns nothing
|
||||
def read_data_to(dir, data)
|
||||
return unless File.directory?(dir) && !@entry_filter.symlink?(dir)
|
||||
|
||||
entries = Dir.chdir(dir) do
|
||||
Dir["*.{yaml,yml,json,csv,tsv}"] + Dir["*"].select { |fn| File.directory?(fn) }
|
||||
end
|
||||
|
||||
entries.each do |entry|
|
||||
path = @site.in_source_dir(dir, entry)
|
||||
next if @entry_filter.symlink?(path)
|
||||
|
||||
if File.directory?(path)
|
||||
read_data_to(path, data[sanitize_filename(entry)] = {})
|
||||
else
|
||||
key = sanitize_filename(File.basename(entry, ".*"))
|
||||
data[key] = read_data_file(path)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Determines how to read a data file.
|
||||
#
|
||||
# Returns the contents of the data file.
|
||||
def read_data_file(path)
|
||||
Jekyll.logger.debug "Reading:", path.sub(@source_dir, "")
|
||||
|
||||
case File.extname(path).downcase
|
||||
when ".csv"
|
||||
CSV.read(path,
|
||||
:headers => true,
|
||||
:encoding => site.config["encoding"]).map(&:to_hash)
|
||||
when ".tsv"
|
||||
CSV.read(path,
|
||||
:col_sep => "\t",
|
||||
:headers => true,
|
||||
:encoding => site.config["encoding"]).map(&:to_hash)
|
||||
else
|
||||
SafeYAML.load_file(path)
|
||||
end
|
||||
end
|
||||
|
||||
def sanitize_filename(name)
|
||||
name.gsub(%r![^\w\s-]+|(?<=^|\b\s)\s+(?=$|\s?\b)!, "")
|
||||
.gsub(%r!\s+!, "_")
|
||||
end
|
||||
end
|
||||
end
|
||||
62
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/readers/layout_reader.rb
vendored
Normal file
62
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/readers/layout_reader.rb
vendored
Normal file
@@ -0,0 +1,62 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Jekyll
|
||||
class LayoutReader
|
||||
attr_reader :site
|
||||
|
||||
def initialize(site)
|
||||
@site = site
|
||||
@layouts = {}
|
||||
end
|
||||
|
||||
def read
|
||||
layout_entries.each do |layout_file|
|
||||
@layouts[layout_name(layout_file)] = \
|
||||
Layout.new(site, layout_directory, layout_file)
|
||||
end
|
||||
|
||||
theme_layout_entries.each do |layout_file|
|
||||
@layouts[layout_name(layout_file)] ||= \
|
||||
Layout.new(site, theme_layout_directory, layout_file)
|
||||
end
|
||||
|
||||
@layouts
|
||||
end
|
||||
|
||||
def layout_directory
|
||||
@layout_directory ||= site.in_source_dir(site.config["layouts_dir"])
|
||||
end
|
||||
|
||||
def theme_layout_directory
|
||||
@theme_layout_directory ||= site.theme.layouts_path if site.theme
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def layout_entries
|
||||
entries_in layout_directory
|
||||
end
|
||||
|
||||
def theme_layout_entries
|
||||
theme_layout_directory ? entries_in(theme_layout_directory) : []
|
||||
end
|
||||
|
||||
def entries_in(dir)
|
||||
entries = []
|
||||
within(dir) do
|
||||
entries = EntryFilter.new(site).filter(Dir["**/*.*"])
|
||||
end
|
||||
entries
|
||||
end
|
||||
|
||||
def layout_name(file)
|
||||
file.split(".")[0..-2].join(".")
|
||||
end
|
||||
|
||||
def within(directory)
|
||||
return unless File.exist?(directory)
|
||||
|
||||
Dir.chdir(directory) { yield }
|
||||
end
|
||||
end
|
||||
end
|
||||
25
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/readers/page_reader.rb
vendored
Normal file
25
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/readers/page_reader.rb
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Jekyll
|
||||
class PageReader
|
||||
attr_reader :site, :dir, :unfiltered_content
|
||||
|
||||
def initialize(site, dir)
|
||||
@site = site
|
||||
@dir = dir
|
||||
@unfiltered_content = []
|
||||
end
|
||||
|
||||
# Create a new `Jekyll::Page` object for each entry in a given array.
|
||||
#
|
||||
# files - An array of file names inside `@dir`
|
||||
#
|
||||
# Returns an array of publishable `Jekyll::Page` objects.
|
||||
def read(files)
|
||||
files.each do |page|
|
||||
@unfiltered_content << Page.new(@site, @site.source, @dir, page)
|
||||
end
|
||||
@unfiltered_content.select { |page| site.publisher.publish?(page) }
|
||||
end
|
||||
end
|
||||
end
|
||||
85
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/readers/post_reader.rb
vendored
Normal file
85
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/readers/post_reader.rb
vendored
Normal file
@@ -0,0 +1,85 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Jekyll
|
||||
class PostReader
|
||||
attr_reader :site, :unfiltered_content
|
||||
|
||||
def initialize(site)
|
||||
@site = site
|
||||
end
|
||||
|
||||
# Read all the files in <source>/<dir>/_drafts and create a new
|
||||
# Document object with each one.
|
||||
#
|
||||
# dir - The String relative path of the directory to read.
|
||||
#
|
||||
# Returns nothing.
|
||||
def read_drafts(dir)
|
||||
read_publishable(dir, "_drafts", Document::DATELESS_FILENAME_MATCHER)
|
||||
end
|
||||
|
||||
# Read all the files in <source>/<dir>/_posts and create a new Document
|
||||
# object with each one.
|
||||
#
|
||||
# dir - The String relative path of the directory to read.
|
||||
#
|
||||
# Returns nothing.
|
||||
def read_posts(dir)
|
||||
read_publishable(dir, "_posts", Document::DATE_FILENAME_MATCHER)
|
||||
end
|
||||
|
||||
# Read all the files in <source>/<dir>/<magic_dir> and create a new
|
||||
# Document object with each one insofar as it matches the regexp matcher.
|
||||
#
|
||||
# dir - The String relative path of the directory to read.
|
||||
#
|
||||
# Returns nothing.
|
||||
def read_publishable(dir, magic_dir, matcher)
|
||||
read_content(dir, magic_dir, matcher)
|
||||
.tap { |docs| docs.each(&:read) }
|
||||
.select { |doc| processable?(doc) }
|
||||
end
|
||||
|
||||
# Read all the content files from <source>/<dir>/magic_dir
|
||||
# and return them with the type klass.
|
||||
#
|
||||
# dir - The String relative path of the directory to read.
|
||||
# magic_dir - The String relative directory to <dir>,
|
||||
# looks for content here.
|
||||
# klass - The return type of the content.
|
||||
#
|
||||
# Returns klass type of content files
|
||||
def read_content(dir, magic_dir, matcher)
|
||||
@site.reader.get_entries(dir, magic_dir).map do |entry|
|
||||
next unless matcher.match?(entry)
|
||||
|
||||
path = @site.in_source_dir(File.join(dir, magic_dir, entry))
|
||||
Document.new(path,
|
||||
:site => @site,
|
||||
:collection => @site.posts)
|
||||
end.tap(&:compact!)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def processable?(doc)
|
||||
if doc.content.nil?
|
||||
Jekyll.logger.debug "Skipping:", "Content in #{doc.relative_path} is nil"
|
||||
false
|
||||
elsif !doc.content.valid_encoding?
|
||||
Jekyll.logger.debug "Skipping:", "#{doc.relative_path} is not valid UTF-8"
|
||||
false
|
||||
else
|
||||
publishable?(doc)
|
||||
end
|
||||
end
|
||||
|
||||
def publishable?(doc)
|
||||
site.publisher.publish?(doc).tap do |will_publish|
|
||||
if !will_publish && site.publisher.hidden_in_the_future?(doc)
|
||||
Jekyll.logger.warn "Skipping:", "#{doc.relative_path} has a future date"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
25
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/readers/static_file_reader.rb
vendored
Normal file
25
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/readers/static_file_reader.rb
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Jekyll
|
||||
class StaticFileReader
|
||||
attr_reader :site, :dir, :unfiltered_content
|
||||
|
||||
def initialize(site, dir)
|
||||
@site = site
|
||||
@dir = dir
|
||||
@unfiltered_content = []
|
||||
end
|
||||
|
||||
# Create a new StaticFile object for every entry in a given list of basenames.
|
||||
#
|
||||
# files - an array of file basenames.
|
||||
#
|
||||
# Returns an array of static files.
|
||||
def read(files)
|
||||
files.each do |file|
|
||||
@unfiltered_content << StaticFile.new(@site, @site.source, @dir, file)
|
||||
end
|
||||
@unfiltered_content
|
||||
end
|
||||
end
|
||||
end
|
||||
52
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/readers/theme_assets_reader.rb
vendored
Normal file
52
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/readers/theme_assets_reader.rb
vendored
Normal file
@@ -0,0 +1,52 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Jekyll
|
||||
class ThemeAssetsReader
|
||||
attr_reader :site
|
||||
|
||||
def initialize(site)
|
||||
@site = site
|
||||
end
|
||||
|
||||
def read
|
||||
return unless site.theme&.assets_path
|
||||
|
||||
Find.find(site.theme.assets_path) do |path|
|
||||
next if File.directory?(path)
|
||||
|
||||
if File.symlink?(path)
|
||||
Jekyll.logger.warn "Theme reader:", "Ignored symlinked asset: #{path}"
|
||||
else
|
||||
read_theme_asset(path)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def read_theme_asset(path)
|
||||
base = site.theme.root
|
||||
dir = File.dirname(path.sub("#{site.theme.root}/", ""))
|
||||
name = File.basename(path)
|
||||
|
||||
if Utils.has_yaml_header?(path)
|
||||
append_unless_exists site.pages,
|
||||
Jekyll::Page.new(site, base, dir, name)
|
||||
else
|
||||
append_unless_exists site.static_files,
|
||||
Jekyll::StaticFile.new(site, base, "/#{dir}", name)
|
||||
end
|
||||
end
|
||||
|
||||
def append_unless_exists(haystack, new_item)
|
||||
if haystack.any? { |file| file.relative_path == new_item.relative_path }
|
||||
Jekyll.logger.debug "Theme:",
|
||||
"Ignoring #{new_item.relative_path} in theme due to existing file " \
|
||||
"with that path in site."
|
||||
return
|
||||
end
|
||||
|
||||
haystack << new_item
|
||||
end
|
||||
end
|
||||
end
|
||||
195
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/regenerator.rb
vendored
Normal file
195
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/regenerator.rb
vendored
Normal file
@@ -0,0 +1,195 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Jekyll
|
||||
class Regenerator
|
||||
attr_reader :site, :metadata, :cache
|
||||
attr_accessor :disabled
|
||||
private :disabled, :disabled=
|
||||
|
||||
def initialize(site)
|
||||
@site = site
|
||||
|
||||
# Read metadata from file
|
||||
read_metadata
|
||||
|
||||
# Initialize cache to an empty hash
|
||||
clear_cache
|
||||
end
|
||||
|
||||
# Checks if a renderable object needs to be regenerated
|
||||
#
|
||||
# Returns a boolean.
|
||||
def regenerate?(document)
|
||||
return true if disabled
|
||||
|
||||
case document
|
||||
when Page
|
||||
regenerate_page?(document)
|
||||
when Document
|
||||
regenerate_document?(document)
|
||||
else
|
||||
source_path = document.respond_to?(:path) ? document.path : nil
|
||||
dest_path = document.destination(@site.dest) if document.respond_to?(:destination)
|
||||
source_modified_or_dest_missing?(source_path, dest_path)
|
||||
end
|
||||
end
|
||||
|
||||
# Add a path to the metadata
|
||||
#
|
||||
# Returns true, also on failure.
|
||||
def add(path)
|
||||
return true unless File.exist?(path)
|
||||
|
||||
metadata[path] = {
|
||||
"mtime" => File.mtime(path),
|
||||
"deps" => [],
|
||||
}
|
||||
cache[path] = true
|
||||
end
|
||||
|
||||
# Force a path to regenerate
|
||||
#
|
||||
# Returns true.
|
||||
def force(path)
|
||||
cache[path] = true
|
||||
end
|
||||
|
||||
# Clear the metadata and cache
|
||||
#
|
||||
# Returns nothing
|
||||
def clear
|
||||
@metadata = {}
|
||||
clear_cache
|
||||
end
|
||||
|
||||
# Clear just the cache
|
||||
#
|
||||
# Returns nothing
|
||||
def clear_cache
|
||||
@cache = {}
|
||||
end
|
||||
|
||||
# Checks if the source has been modified or the
|
||||
# destination is missing
|
||||
#
|
||||
# returns a boolean
|
||||
def source_modified_or_dest_missing?(source_path, dest_path)
|
||||
modified?(source_path) || (dest_path && !File.exist?(dest_path))
|
||||
end
|
||||
|
||||
# Checks if a path's (or one of its dependencies)
|
||||
# mtime has changed
|
||||
#
|
||||
# Returns a boolean.
|
||||
def modified?(path)
|
||||
return true if disabled?
|
||||
|
||||
# objects that don't have a path are always regenerated
|
||||
return true if path.nil?
|
||||
|
||||
# Check for path in cache
|
||||
return cache[path] if cache.key? path
|
||||
|
||||
if metadata[path]
|
||||
# If we have seen this file before,
|
||||
# check if it or one of its dependencies has been modified
|
||||
existing_file_modified?(path)
|
||||
else
|
||||
# If we have not seen this file before, add it to the metadata and regenerate it
|
||||
add(path)
|
||||
end
|
||||
end
|
||||
|
||||
# Add a dependency of a path
|
||||
#
|
||||
# Returns nothing.
|
||||
def add_dependency(path, dependency)
|
||||
return if metadata[path].nil? || disabled
|
||||
|
||||
unless metadata[path]["deps"].include? dependency
|
||||
metadata[path]["deps"] << dependency
|
||||
add(dependency) unless metadata.include?(dependency)
|
||||
end
|
||||
regenerate? dependency
|
||||
end
|
||||
|
||||
# Write the metadata to disk
|
||||
#
|
||||
# Returns nothing.
|
||||
def write_metadata
|
||||
unless disabled?
|
||||
Jekyll.logger.debug "Writing Metadata:", ".jekyll-metadata"
|
||||
File.binwrite(metadata_file, Marshal.dump(metadata))
|
||||
end
|
||||
end
|
||||
|
||||
# Produce the absolute path of the metadata file
|
||||
#
|
||||
# Returns the String path of the file.
|
||||
def metadata_file
|
||||
@metadata_file ||= site.in_source_dir(".jekyll-metadata")
|
||||
end
|
||||
|
||||
# Check if metadata has been disabled
|
||||
#
|
||||
# Returns a Boolean (true for disabled, false for enabled).
|
||||
def disabled?
|
||||
self.disabled = !site.incremental? if disabled.nil?
|
||||
disabled
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# Read metadata from the metadata file, if no file is found,
|
||||
# initialize with an empty hash
|
||||
#
|
||||
# Returns the read metadata.
|
||||
def read_metadata
|
||||
@metadata =
|
||||
if !disabled? && File.file?(metadata_file)
|
||||
content = File.binread(metadata_file)
|
||||
|
||||
begin
|
||||
Marshal.load(content)
|
||||
rescue TypeError
|
||||
SafeYAML.load(content)
|
||||
rescue ArgumentError => e
|
||||
Jekyll.logger.warn("Failed to load #{metadata_file}: #{e}")
|
||||
{}
|
||||
end
|
||||
else
|
||||
{}
|
||||
end
|
||||
end
|
||||
|
||||
def regenerate_page?(document)
|
||||
document.asset_file? || document.data["regenerate"] ||
|
||||
source_modified_or_dest_missing?(
|
||||
site.in_source_dir(document.relative_path), document.destination(@site.dest)
|
||||
)
|
||||
end
|
||||
|
||||
def regenerate_document?(document)
|
||||
!document.write? || document.data["regenerate"] ||
|
||||
source_modified_or_dest_missing?(
|
||||
document.path, document.destination(@site.dest)
|
||||
)
|
||||
end
|
||||
|
||||
def existing_file_modified?(path)
|
||||
# If one of this file dependencies have been modified,
|
||||
# set the regeneration bit for both the dependency and the file to true
|
||||
metadata[path]["deps"].each do |dependency|
|
||||
return cache[dependency] = cache[path] = true if modified?(dependency)
|
||||
end
|
||||
|
||||
if File.exist?(path) && metadata[path]["mtime"].eql?(File.mtime(path))
|
||||
# If this file has not been modified, set the regeneration bit to false
|
||||
cache[path] = false
|
||||
else
|
||||
# If it has been modified, set it to true
|
||||
add(path)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
52
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/related_posts.rb
vendored
Normal file
52
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/related_posts.rb
vendored
Normal file
@@ -0,0 +1,52 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Jekyll
|
||||
class RelatedPosts
|
||||
class << self
|
||||
attr_accessor :lsi
|
||||
end
|
||||
|
||||
attr_reader :post, :site
|
||||
|
||||
def initialize(post)
|
||||
@post = post
|
||||
@site = post.site
|
||||
Jekyll::External.require_with_graceful_fail("classifier-reborn") if site.lsi
|
||||
end
|
||||
|
||||
def build
|
||||
return [] unless site.posts.docs.size > 1
|
||||
|
||||
if site.lsi
|
||||
build_index
|
||||
lsi_related_posts
|
||||
else
|
||||
most_recent_posts
|
||||
end
|
||||
end
|
||||
|
||||
def build_index
|
||||
self.class.lsi ||= begin
|
||||
lsi = ClassifierReborn::LSI.new(:auto_rebuild => false)
|
||||
Jekyll.logger.info("Populating LSI...")
|
||||
|
||||
site.posts.docs.each do |x|
|
||||
lsi.add_item(x)
|
||||
end
|
||||
|
||||
Jekyll.logger.info("Rebuilding index...")
|
||||
lsi.build_index
|
||||
Jekyll.logger.info("")
|
||||
lsi
|
||||
end
|
||||
end
|
||||
|
||||
def lsi_related_posts
|
||||
self.class.lsi.find_related(post, 11)
|
||||
end
|
||||
|
||||
def most_recent_posts
|
||||
@most_recent_posts ||= (site.posts.docs.last(11).reverse! - [post]).first(10)
|
||||
end
|
||||
end
|
||||
end
|
||||
265
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/renderer.rb
vendored
Normal file
265
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/renderer.rb
vendored
Normal file
@@ -0,0 +1,265 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Jekyll
|
||||
class Renderer
|
||||
attr_reader :document, :site
|
||||
attr_writer :layouts, :payload
|
||||
|
||||
def initialize(site, document, site_payload = nil)
|
||||
@site = site
|
||||
@document = document
|
||||
@payload = site_payload
|
||||
@layouts = nil
|
||||
end
|
||||
|
||||
# Fetches the payload used in Liquid rendering.
|
||||
# It can be written with #payload=(new_payload)
|
||||
# Falls back to site.site_payload if no payload is set.
|
||||
#
|
||||
# Returns a Jekyll::Drops::UnifiedPayloadDrop
|
||||
def payload
|
||||
@payload ||= site.site_payload
|
||||
end
|
||||
|
||||
# The list of layouts registered for this Renderer.
|
||||
# It can be written with #layouts=(new_layouts)
|
||||
# Falls back to site.layouts if no layouts are registered.
|
||||
#
|
||||
# Returns a Hash of String => Jekyll::Layout identified
|
||||
# as basename without the extension name.
|
||||
def layouts
|
||||
@layouts || site.layouts
|
||||
end
|
||||
|
||||
# Determine which converters to use based on this document's
|
||||
# extension.
|
||||
#
|
||||
# Returns Array of Converter instances.
|
||||
def converters
|
||||
@converters ||= site.converters.select { |c| c.matches(document.extname) }.tap(&:sort!)
|
||||
end
|
||||
|
||||
# Determine the extname the outputted file should have
|
||||
#
|
||||
# Returns String the output extname including the leading period.
|
||||
def output_ext
|
||||
@output_ext ||= (permalink_ext || converter_output_ext)
|
||||
end
|
||||
|
||||
# Prepare payload and render the document
|
||||
#
|
||||
# Returns String rendered document output
|
||||
def run
|
||||
Jekyll.logger.debug "Rendering:", document.relative_path
|
||||
|
||||
assign_pages!
|
||||
assign_current_document!
|
||||
assign_highlighter_options!
|
||||
assign_layout_data!
|
||||
|
||||
Jekyll.logger.debug "Pre-Render Hooks:", document.relative_path
|
||||
document.trigger_hooks(:pre_render, payload)
|
||||
|
||||
render_document
|
||||
end
|
||||
|
||||
# Render the document.
|
||||
#
|
||||
# Returns String rendered document output
|
||||
# rubocop: disable Metrics/AbcSize, Metrics/MethodLength
|
||||
def render_document
|
||||
info = {
|
||||
:registers => { :site => site, :page => payload["page"] },
|
||||
:strict_filters => liquid_options["strict_filters"],
|
||||
:strict_variables => liquid_options["strict_variables"],
|
||||
}
|
||||
|
||||
output = document.content
|
||||
if document.render_with_liquid?
|
||||
Jekyll.logger.debug "Rendering Liquid:", document.relative_path
|
||||
output = render_liquid(output, payload, info, document.path)
|
||||
end
|
||||
|
||||
Jekyll.logger.debug "Rendering Markup:", document.relative_path
|
||||
output = convert(output.to_s)
|
||||
document.content = output
|
||||
|
||||
Jekyll.logger.debug "Post-Convert Hooks:", document.relative_path
|
||||
document.trigger_hooks(:post_convert)
|
||||
output = document.content
|
||||
|
||||
if document.place_in_layout?
|
||||
Jekyll.logger.debug "Rendering Layout:", document.relative_path
|
||||
output = place_in_layouts(output, payload, info)
|
||||
end
|
||||
|
||||
output
|
||||
end
|
||||
# rubocop: enable Metrics/AbcSize, Metrics/MethodLength
|
||||
|
||||
# Convert the document using the converters which match this renderer's document.
|
||||
#
|
||||
# Returns String the converted content.
|
||||
def convert(content)
|
||||
converters.reduce(content) do |output, converter|
|
||||
begin
|
||||
converter.convert output
|
||||
rescue StandardError => e
|
||||
Jekyll.logger.error "Conversion error:",
|
||||
"#{converter.class} encountered an error while "\
|
||||
"converting '#{document.relative_path}':"
|
||||
Jekyll.logger.error("", e.to_s)
|
||||
raise e
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Render the given content with the payload and info
|
||||
#
|
||||
# content -
|
||||
# payload -
|
||||
# info -
|
||||
# path - (optional) the path to the file, for use in ex
|
||||
#
|
||||
# Returns String the content, rendered by Liquid.
|
||||
def render_liquid(content, payload, info, path = nil)
|
||||
template = site.liquid_renderer.file(path).parse(content)
|
||||
template.warnings.each do |e|
|
||||
Jekyll.logger.warn "Liquid Warning:",
|
||||
LiquidRenderer.format_error(e, path || document.relative_path)
|
||||
end
|
||||
template.render!(payload, info)
|
||||
# rubocop: disable Lint/RescueException
|
||||
rescue Exception => e
|
||||
Jekyll.logger.error "Liquid Exception:",
|
||||
LiquidRenderer.format_error(e, path || document.relative_path)
|
||||
raise e
|
||||
end
|
||||
# rubocop: enable Lint/RescueException
|
||||
|
||||
# Checks if the layout specified in the document actually exists
|
||||
#
|
||||
# layout - the layout to check
|
||||
#
|
||||
# Returns Boolean true if the layout is invalid, false if otherwise
|
||||
def invalid_layout?(layout)
|
||||
!document.data["layout"].nil? && layout.nil? && !(document.is_a? Jekyll::Excerpt)
|
||||
end
|
||||
|
||||
# Render layouts and place document content inside.
|
||||
#
|
||||
# Returns String rendered content
|
||||
def place_in_layouts(content, payload, info)
|
||||
output = content.dup
|
||||
layout = layouts[document.data["layout"].to_s]
|
||||
validate_layout(layout)
|
||||
|
||||
used = Set.new([layout])
|
||||
|
||||
# Reset the payload layout data to ensure it starts fresh for each page.
|
||||
payload["layout"] = nil
|
||||
|
||||
while layout
|
||||
output = render_layout(output, layout, info)
|
||||
add_regenerator_dependencies(layout)
|
||||
|
||||
next unless (layout = site.layouts[layout.data["layout"]])
|
||||
break if used.include?(layout)
|
||||
|
||||
used << layout
|
||||
end
|
||||
output
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# Checks if the layout specified in the document actually exists
|
||||
#
|
||||
# layout - the layout to check
|
||||
# Returns nothing
|
||||
def validate_layout(layout)
|
||||
return unless invalid_layout?(layout)
|
||||
|
||||
Jekyll.logger.warn "Build Warning:", "Layout '#{document.data["layout"]}' requested " \
|
||||
"in #{document.relative_path} does not exist."
|
||||
end
|
||||
|
||||
# Render layout content into document.output
|
||||
#
|
||||
# Returns String rendered content
|
||||
def render_layout(output, layout, info)
|
||||
payload["content"] = output
|
||||
payload["layout"] = Utils.deep_merge_hashes(layout.data, payload["layout"] || {})
|
||||
|
||||
render_liquid(
|
||||
layout.content,
|
||||
payload,
|
||||
info,
|
||||
layout.path
|
||||
)
|
||||
end
|
||||
|
||||
def add_regenerator_dependencies(layout)
|
||||
return unless document.write?
|
||||
|
||||
site.regenerator.add_dependency(
|
||||
site.in_source_dir(document.path),
|
||||
layout.path
|
||||
)
|
||||
end
|
||||
|
||||
# Set page content to payload and assign pager if document has one.
|
||||
#
|
||||
# Returns nothing
|
||||
def assign_pages!
|
||||
payload["page"] = document.to_liquid
|
||||
payload["paginator"] = (document.pager.to_liquid if document.respond_to?(:pager))
|
||||
end
|
||||
|
||||
# Set related posts to payload if document is a post.
|
||||
#
|
||||
# Returns nothing
|
||||
def assign_current_document!
|
||||
payload["site"].current_document = document
|
||||
end
|
||||
|
||||
# Set highlighter prefix and suffix
|
||||
#
|
||||
# Returns nothing
|
||||
def assign_highlighter_options!
|
||||
payload["highlighter_prefix"] = converters.first.highlighter_prefix
|
||||
payload["highlighter_suffix"] = converters.first.highlighter_suffix
|
||||
end
|
||||
|
||||
def assign_layout_data!
|
||||
layout = layouts[document.data["layout"]]
|
||||
payload["layout"] = Utils.deep_merge_hashes(layout.data, payload["layout"] || {}) if layout
|
||||
end
|
||||
|
||||
def permalink_ext
|
||||
document_permalink = document.permalink
|
||||
if document_permalink && !document_permalink.end_with?("/")
|
||||
permalink_ext = File.extname(document_permalink)
|
||||
permalink_ext unless permalink_ext.empty?
|
||||
end
|
||||
end
|
||||
|
||||
def converter_output_ext
|
||||
if output_exts.size == 1
|
||||
output_exts.last
|
||||
else
|
||||
output_exts[-2]
|
||||
end
|
||||
end
|
||||
|
||||
def output_exts
|
||||
@output_exts ||= converters.map do |c|
|
||||
c.output_ext(document.extname)
|
||||
end.tap(&:compact!)
|
||||
end
|
||||
|
||||
def liquid_options
|
||||
@liquid_options ||= site.config["liquid"]
|
||||
end
|
||||
end
|
||||
end
|
||||
551
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/site.rb
vendored
Normal file
551
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/site.rb
vendored
Normal file
@@ -0,0 +1,551 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Jekyll
|
||||
class Site
|
||||
attr_reader :source, :dest, :cache_dir, :config
|
||||
attr_accessor :layouts, :pages, :static_files, :drafts, :inclusions,
|
||||
:exclude, :include, :lsi, :highlighter, :permalink_style,
|
||||
:time, :future, :unpublished, :safe, :plugins, :limit_posts,
|
||||
:show_drafts, :keep_files, :baseurl, :data, :file_read_opts,
|
||||
:gems, :plugin_manager, :theme
|
||||
|
||||
attr_accessor :converters, :generators, :reader
|
||||
attr_reader :regenerator, :liquid_renderer, :includes_load_paths, :filter_cache, :profiler
|
||||
|
||||
# Public: Initialize a new Site.
|
||||
#
|
||||
# config - A Hash containing site configuration details.
|
||||
def initialize(config)
|
||||
# Source and destination may not be changed after the site has been created.
|
||||
@source = File.expand_path(config["source"]).freeze
|
||||
@dest = File.expand_path(config["destination"]).freeze
|
||||
|
||||
self.config = config
|
||||
|
||||
@cache_dir = in_source_dir(config["cache_dir"])
|
||||
@filter_cache = {}
|
||||
|
||||
@reader = Reader.new(self)
|
||||
@profiler = Profiler.new(self)
|
||||
@regenerator = Regenerator.new(self)
|
||||
@liquid_renderer = LiquidRenderer.new(self)
|
||||
|
||||
Jekyll.sites << self
|
||||
|
||||
reset
|
||||
setup
|
||||
|
||||
Jekyll::Hooks.trigger :site, :after_init, self
|
||||
end
|
||||
|
||||
# Public: Set the site's configuration. This handles side-effects caused by
|
||||
# changing values in the configuration.
|
||||
#
|
||||
# config - a Jekyll::Configuration, containing the new configuration.
|
||||
#
|
||||
# Returns the new configuration.
|
||||
def config=(config)
|
||||
@config = config.clone
|
||||
|
||||
%w(safe lsi highlighter baseurl exclude include future unpublished
|
||||
show_drafts limit_posts keep_files).each do |opt|
|
||||
send("#{opt}=", config[opt])
|
||||
end
|
||||
|
||||
# keep using `gems` to avoid breaking change
|
||||
self.gems = config["plugins"]
|
||||
|
||||
configure_cache
|
||||
configure_plugins
|
||||
configure_theme
|
||||
configure_include_paths
|
||||
configure_file_read_opts
|
||||
|
||||
self.permalink_style = config["permalink"].to_sym
|
||||
|
||||
# Read in a _config.yml from the current theme-gem at the very end.
|
||||
@config = load_theme_configuration(config) if theme
|
||||
@config
|
||||
end
|
||||
|
||||
# Public: Read, process, and write this Site to output.
|
||||
#
|
||||
# Returns nothing.
|
||||
def process
|
||||
return profiler.profile_process if config["profile"]
|
||||
|
||||
reset
|
||||
read
|
||||
generate
|
||||
render
|
||||
cleanup
|
||||
write
|
||||
end
|
||||
|
||||
def print_stats
|
||||
Jekyll.logger.info @liquid_renderer.stats_table
|
||||
end
|
||||
|
||||
# rubocop:disable Metrics/AbcSize
|
||||
# rubocop:disable Metrics/MethodLength
|
||||
#
|
||||
# Reset Site details.
|
||||
#
|
||||
# Returns nothing
|
||||
def reset
|
||||
self.time = if config["time"]
|
||||
Utils.parse_date(config["time"].to_s, "Invalid time in _config.yml.")
|
||||
else
|
||||
Time.now
|
||||
end
|
||||
self.layouts = {}
|
||||
self.inclusions = {}
|
||||
self.pages = []
|
||||
self.static_files = []
|
||||
self.data = {}
|
||||
@post_attr_hash = {}
|
||||
@site_data = nil
|
||||
@collections = nil
|
||||
@documents = nil
|
||||
@docs_to_write = nil
|
||||
@regenerator.clear_cache
|
||||
@liquid_renderer.reset
|
||||
@site_cleaner = nil
|
||||
frontmatter_defaults.reset
|
||||
|
||||
raise ArgumentError, "limit_posts must be a non-negative number" if limit_posts.negative?
|
||||
|
||||
Jekyll::Cache.clear_if_config_changed config
|
||||
Jekyll::Hooks.trigger :site, :after_reset, self
|
||||
nil
|
||||
end
|
||||
# rubocop:enable Metrics/MethodLength
|
||||
# rubocop:enable Metrics/AbcSize
|
||||
|
||||
# Load necessary libraries, plugins, converters, and generators.
|
||||
#
|
||||
# Returns nothing.
|
||||
def setup
|
||||
ensure_not_in_dest
|
||||
|
||||
plugin_manager.conscientious_require
|
||||
|
||||
self.converters = instantiate_subclasses(Jekyll::Converter)
|
||||
self.generators = instantiate_subclasses(Jekyll::Generator)
|
||||
end
|
||||
|
||||
# Check that the destination dir isn't the source dir or a directory
|
||||
# parent to the source dir.
|
||||
def ensure_not_in_dest
|
||||
dest_pathname = Pathname.new(dest)
|
||||
Pathname.new(source).ascend do |path|
|
||||
if path == dest_pathname
|
||||
raise Errors::FatalException,
|
||||
"Destination directory cannot be or contain the Source directory."
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# The list of collections and their corresponding Jekyll::Collection instances.
|
||||
# If config['collections'] is set, a new instance is created
|
||||
# for each item in the collection, a new hash is returned otherwise.
|
||||
#
|
||||
# Returns a Hash containing collection name-to-instance pairs.
|
||||
def collections
|
||||
@collections ||= collection_names.each_with_object({}) do |name, hsh|
|
||||
hsh[name] = Jekyll::Collection.new(self, name)
|
||||
end
|
||||
end
|
||||
|
||||
# The list of collection names.
|
||||
#
|
||||
# Returns an array of collection names from the configuration,
|
||||
# or an empty array if the `collections` key is not set.
|
||||
def collection_names
|
||||
case config["collections"]
|
||||
when Hash
|
||||
config["collections"].keys
|
||||
when Array
|
||||
config["collections"]
|
||||
when nil
|
||||
[]
|
||||
else
|
||||
raise ArgumentError, "Your `collections` key must be a hash or an array."
|
||||
end
|
||||
end
|
||||
|
||||
# Read Site data from disk and load it into internal data structures.
|
||||
#
|
||||
# Returns nothing.
|
||||
def read
|
||||
reader.read
|
||||
limit_posts!
|
||||
Jekyll::Hooks.trigger :site, :post_read, self
|
||||
nil
|
||||
end
|
||||
|
||||
# Run each of the Generators.
|
||||
#
|
||||
# Returns nothing.
|
||||
def generate
|
||||
generators.each do |generator|
|
||||
start = Time.now
|
||||
generator.generate(self)
|
||||
Jekyll.logger.debug "Generating:",
|
||||
"#{generator.class} finished in #{Time.now - start} seconds."
|
||||
end
|
||||
nil
|
||||
end
|
||||
|
||||
# Render the site to the destination.
|
||||
#
|
||||
# Returns nothing.
|
||||
def render
|
||||
relative_permalinks_are_deprecated
|
||||
|
||||
payload = site_payload
|
||||
|
||||
Jekyll::Hooks.trigger :site, :pre_render, self, payload
|
||||
|
||||
render_docs(payload)
|
||||
render_pages(payload)
|
||||
|
||||
Jekyll::Hooks.trigger :site, :post_render, self, payload
|
||||
nil
|
||||
end
|
||||
|
||||
# Remove orphaned files and empty directories in destination.
|
||||
#
|
||||
# Returns nothing.
|
||||
def cleanup
|
||||
site_cleaner.cleanup!
|
||||
nil
|
||||
end
|
||||
|
||||
# Write static files, pages, and posts.
|
||||
#
|
||||
# Returns nothing.
|
||||
def write
|
||||
Jekyll::Commands::Doctor.conflicting_urls(self)
|
||||
each_site_file do |item|
|
||||
item.write(dest) if regenerator.regenerate?(item)
|
||||
end
|
||||
regenerator.write_metadata
|
||||
Jekyll::Hooks.trigger :site, :post_write, self
|
||||
nil
|
||||
end
|
||||
|
||||
def posts
|
||||
collections["posts"] ||= Collection.new(self, "posts")
|
||||
end
|
||||
|
||||
# Construct a Hash of Posts indexed by the specified Post attribute.
|
||||
#
|
||||
# post_attr - The String name of the Post attribute.
|
||||
#
|
||||
# Examples
|
||||
#
|
||||
# post_attr_hash('categories')
|
||||
# # => { 'tech' => [<Post A>, <Post B>],
|
||||
# # 'ruby' => [<Post B>] }
|
||||
#
|
||||
# Returns the Hash: { attr => posts } where
|
||||
# attr - One of the values for the requested attribute.
|
||||
# posts - The Array of Posts with the given attr value.
|
||||
def post_attr_hash(post_attr)
|
||||
# Build a hash map based on the specified post attribute ( post attr =>
|
||||
# array of posts ) then sort each array in reverse order.
|
||||
@post_attr_hash[post_attr] ||= begin
|
||||
hash = Hash.new { |h, key| h[key] = [] }
|
||||
posts.docs.each do |p|
|
||||
p.data[post_attr]&.each { |t| hash[t] << p }
|
||||
end
|
||||
hash.each_value { |posts| posts.sort!.reverse! }
|
||||
hash
|
||||
end
|
||||
end
|
||||
|
||||
def tags
|
||||
post_attr_hash("tags")
|
||||
end
|
||||
|
||||
def categories
|
||||
post_attr_hash("categories")
|
||||
end
|
||||
|
||||
# Prepare site data for site payload. The method maintains backward compatibility
|
||||
# if the key 'data' is already used in _config.yml.
|
||||
#
|
||||
# Returns the Hash to be hooked to site.data.
|
||||
def site_data
|
||||
@site_data ||= (config["data"] || data)
|
||||
end
|
||||
|
||||
# The Hash payload containing site-wide data.
|
||||
#
|
||||
# Returns the Hash: { "site" => data } where data is a Hash with keys:
|
||||
# "time" - The Time as specified in the configuration or the
|
||||
# current time if none was specified.
|
||||
# "posts" - The Array of Posts, sorted chronologically by post date
|
||||
# and then title.
|
||||
# "pages" - The Array of all Pages.
|
||||
# "html_pages" - The Array of HTML Pages.
|
||||
# "categories" - The Hash of category values and Posts.
|
||||
# See Site#post_attr_hash for type info.
|
||||
# "tags" - The Hash of tag values and Posts.
|
||||
# See Site#post_attr_hash for type info.
|
||||
def site_payload
|
||||
Drops::UnifiedPayloadDrop.new self
|
||||
end
|
||||
alias_method :to_liquid, :site_payload
|
||||
|
||||
# Get the implementation class for the given Converter.
|
||||
# Returns the Converter instance implementing the given Converter.
|
||||
# klass - The Class of the Converter to fetch.
|
||||
def find_converter_instance(klass)
|
||||
@find_converter_instance ||= {}
|
||||
@find_converter_instance[klass] ||= begin
|
||||
converters.find { |converter| converter.instance_of?(klass) } || \
|
||||
raise("No Converters found for #{klass}")
|
||||
end
|
||||
end
|
||||
|
||||
# klass - class or module containing the subclasses.
|
||||
# Returns array of instances of subclasses of parameter.
|
||||
# Create array of instances of the subclasses of the class or module
|
||||
# passed in as argument.
|
||||
|
||||
def instantiate_subclasses(klass)
|
||||
klass.descendants.select { |c| !safe || c.safe }.tap do |result|
|
||||
result.sort!
|
||||
result.map! { |c| c.new(config) }
|
||||
end
|
||||
end
|
||||
|
||||
# Warns the user if permanent links are relative to the parent
|
||||
# directory. As this is a deprecated function of Jekyll.
|
||||
#
|
||||
# Returns
|
||||
def relative_permalinks_are_deprecated
|
||||
if config["relative_permalinks"]
|
||||
Jekyll.logger.abort_with "Since v3.0, permalinks for pages" \
|
||||
" in subfolders must be relative to the" \
|
||||
" site source directory, not the parent" \
|
||||
" directory. Check https://jekyllrb.com/docs/upgrading/"\
|
||||
" for more info."
|
||||
end
|
||||
end
|
||||
|
||||
# Get the to be written documents
|
||||
#
|
||||
# Returns an Array of Documents which should be written
|
||||
def docs_to_write
|
||||
documents.select(&:write?)
|
||||
end
|
||||
|
||||
# Get all the documents
|
||||
#
|
||||
# Returns an Array of all Documents
|
||||
def documents
|
||||
collections.each_with_object(Set.new) do |(_, collection), set|
|
||||
set.merge(collection.docs).merge(collection.files)
|
||||
end.to_a
|
||||
end
|
||||
|
||||
def each_site_file
|
||||
%w(pages static_files docs_to_write).each do |type|
|
||||
send(type).each do |item|
|
||||
yield item
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Returns the FrontmatterDefaults or creates a new FrontmatterDefaults
|
||||
# if it doesn't already exist.
|
||||
#
|
||||
# Returns The FrontmatterDefaults
|
||||
def frontmatter_defaults
|
||||
@frontmatter_defaults ||= FrontmatterDefaults.new(self)
|
||||
end
|
||||
|
||||
# Whether to perform a full rebuild without incremental regeneration
|
||||
#
|
||||
# Returns a Boolean: true for a full rebuild, false for normal build
|
||||
def incremental?(override = {})
|
||||
override["incremental"] || config["incremental"]
|
||||
end
|
||||
|
||||
# Returns the publisher or creates a new publisher if it doesn't
|
||||
# already exist.
|
||||
#
|
||||
# Returns The Publisher
|
||||
def publisher
|
||||
@publisher ||= Publisher.new(self)
|
||||
end
|
||||
|
||||
# Public: Prefix a given path with the source directory.
|
||||
#
|
||||
# paths - (optional) path elements to a file or directory within the
|
||||
# source directory
|
||||
#
|
||||
# Returns a path which is prefixed with the source directory.
|
||||
def in_source_dir(*paths)
|
||||
paths.reduce(source) do |base, path|
|
||||
Jekyll.sanitized_path(base, path)
|
||||
end
|
||||
end
|
||||
|
||||
# Public: Prefix a given path with the theme directory.
|
||||
#
|
||||
# paths - (optional) path elements to a file or directory within the
|
||||
# theme directory
|
||||
#
|
||||
# Returns a path which is prefixed with the theme root directory.
|
||||
def in_theme_dir(*paths)
|
||||
return nil unless theme
|
||||
|
||||
paths.reduce(theme.root) do |base, path|
|
||||
Jekyll.sanitized_path(base, path)
|
||||
end
|
||||
end
|
||||
|
||||
# Public: Prefix a given path with the destination directory.
|
||||
#
|
||||
# paths - (optional) path elements to a file or directory within the
|
||||
# destination directory
|
||||
#
|
||||
# Returns a path which is prefixed with the destination directory.
|
||||
def in_dest_dir(*paths)
|
||||
paths.reduce(dest) do |base, path|
|
||||
Jekyll.sanitized_path(base, path)
|
||||
end
|
||||
end
|
||||
|
||||
# Public: Prefix a given path with the cache directory.
|
||||
#
|
||||
# paths - (optional) path elements to a file or directory within the
|
||||
# cache directory
|
||||
#
|
||||
# Returns a path which is prefixed with the cache directory.
|
||||
def in_cache_dir(*paths)
|
||||
paths.reduce(cache_dir) do |base, path|
|
||||
Jekyll.sanitized_path(base, path)
|
||||
end
|
||||
end
|
||||
|
||||
# Public: The full path to the directory that houses all the collections registered
|
||||
# with the current site.
|
||||
#
|
||||
# Returns the source directory or the absolute path to the custom collections_dir
|
||||
def collections_path
|
||||
dir_str = config["collections_dir"]
|
||||
@collections_path ||= dir_str.empty? ? source : in_source_dir(dir_str)
|
||||
end
|
||||
|
||||
# Public
|
||||
#
|
||||
# Returns the object as a debug String.
|
||||
def inspect
|
||||
"#<#{self.class} @source=#{@source}>"
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def load_theme_configuration(config)
|
||||
return config if config["ignore_theme_config"] == true
|
||||
|
||||
theme_config_file = in_theme_dir("_config.yml")
|
||||
return config unless File.exist?(theme_config_file)
|
||||
|
||||
# Bail out if the theme_config_file is a symlink file irrespective of safe mode
|
||||
return config if File.symlink?(theme_config_file)
|
||||
|
||||
theme_config = SafeYAML.load_file(theme_config_file)
|
||||
return config unless theme_config.is_a?(Hash)
|
||||
|
||||
Jekyll.logger.info "Theme Config file:", theme_config_file
|
||||
|
||||
# theme_config should not be overriding Jekyll's defaults
|
||||
theme_config.delete_if { |key, _| Configuration::DEFAULTS.key?(key) }
|
||||
|
||||
# Override theme_config with existing config and return the result.
|
||||
Utils.deep_merge_hashes(theme_config, config)
|
||||
end
|
||||
|
||||
# Limits the current posts; removes the posts which exceed the limit_posts
|
||||
#
|
||||
# Returns nothing
|
||||
def limit_posts!
|
||||
if limit_posts.positive?
|
||||
limit = posts.docs.length < limit_posts ? posts.docs.length : limit_posts
|
||||
posts.docs = posts.docs[-limit, limit]
|
||||
end
|
||||
end
|
||||
|
||||
# Returns the Cleaner or creates a new Cleaner if it doesn't
|
||||
# already exist.
|
||||
#
|
||||
# Returns The Cleaner
|
||||
def site_cleaner
|
||||
@site_cleaner ||= Cleaner.new(self)
|
||||
end
|
||||
|
||||
# Disable Marshaling cache to disk in Safe Mode
|
||||
def configure_cache
|
||||
Jekyll::Cache.cache_dir = in_source_dir(config["cache_dir"], "Jekyll/Cache")
|
||||
Jekyll::Cache.disable_disk_cache! if safe || config["disable_disk_cache"]
|
||||
end
|
||||
|
||||
def configure_plugins
|
||||
self.plugin_manager = Jekyll::PluginManager.new(self)
|
||||
self.plugins = plugin_manager.plugins_path
|
||||
end
|
||||
|
||||
def configure_theme
|
||||
self.theme = nil
|
||||
return if config["theme"].nil?
|
||||
|
||||
self.theme =
|
||||
if config["theme"].is_a?(String)
|
||||
Jekyll::Theme.new(config["theme"])
|
||||
else
|
||||
Jekyll.logger.warn "Theme:", "value of 'theme' in config should be " \
|
||||
"String to use gem-based themes, but got #{config["theme"].class}"
|
||||
nil
|
||||
end
|
||||
end
|
||||
|
||||
def configure_include_paths
|
||||
@includes_load_paths = Array(in_source_dir(config["includes_dir"].to_s))
|
||||
@includes_load_paths << theme.includes_path if theme&.includes_path
|
||||
end
|
||||
|
||||
def configure_file_read_opts
|
||||
self.file_read_opts = {}
|
||||
file_read_opts[:encoding] = config["encoding"] if config["encoding"]
|
||||
self.file_read_opts = Jekyll::Utils.merged_file_read_opts(self, {})
|
||||
end
|
||||
|
||||
def render_docs(payload)
|
||||
collections.each_value do |collection|
|
||||
collection.docs.each do |document|
|
||||
render_regenerated(document, payload)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def render_pages(payload)
|
||||
pages.each do |page|
|
||||
render_regenerated(page, payload)
|
||||
end
|
||||
end
|
||||
|
||||
def render_regenerated(document, payload)
|
||||
return unless regenerator.regenerate?(document)
|
||||
|
||||
document.renderer.payload = payload
|
||||
document.output = document.renderer.run
|
||||
document.trigger_hooks(:post_render)
|
||||
end
|
||||
end
|
||||
end
|
||||
208
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/static_file.rb
vendored
Normal file
208
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/static_file.rb
vendored
Normal file
@@ -0,0 +1,208 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Jekyll
|
||||
class StaticFile
|
||||
extend Forwardable
|
||||
|
||||
attr_reader :relative_path, :extname, :name
|
||||
|
||||
def_delegator :to_liquid, :to_json, :to_json
|
||||
|
||||
class << self
|
||||
# The cache of last modification times [path] -> mtime.
|
||||
def mtimes
|
||||
@mtimes ||= {}
|
||||
end
|
||||
|
||||
def reset_cache
|
||||
@mtimes = nil
|
||||
end
|
||||
end
|
||||
|
||||
# Initialize a new StaticFile.
|
||||
#
|
||||
# site - The Site.
|
||||
# base - The String path to the <source>.
|
||||
# dir - The String path between <source> and the file.
|
||||
# name - The String filename of the file.
|
||||
# rubocop: disable Metrics/ParameterLists
|
||||
def initialize(site, base, dir, name, collection = nil)
|
||||
@site = site
|
||||
@base = base
|
||||
@dir = dir
|
||||
@name = name
|
||||
@collection = collection
|
||||
@relative_path = File.join(*[@dir, @name].compact)
|
||||
@extname = File.extname(@name)
|
||||
end
|
||||
# rubocop: enable Metrics/ParameterLists
|
||||
|
||||
# Returns source file path.
|
||||
def path
|
||||
@path ||= begin
|
||||
# Static file is from a collection inside custom collections directory
|
||||
if !@collection.nil? && !@site.config["collections_dir"].empty?
|
||||
File.join(*[@base, @site.config["collections_dir"], @dir, @name].compact)
|
||||
else
|
||||
File.join(*[@base, @dir, @name].compact)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Obtain destination path.
|
||||
#
|
||||
# dest - The String path to the destination dir.
|
||||
#
|
||||
# Returns destination file path.
|
||||
def destination(dest)
|
||||
@destination ||= {}
|
||||
@destination[dest] ||= @site.in_dest_dir(dest, Jekyll::URL.unescape_path(url))
|
||||
end
|
||||
|
||||
def destination_rel_dir
|
||||
if @collection
|
||||
File.dirname(url)
|
||||
else
|
||||
@dir
|
||||
end
|
||||
end
|
||||
|
||||
def modified_time
|
||||
@modified_time ||= File.stat(path).mtime
|
||||
end
|
||||
|
||||
# Returns last modification time for this file.
|
||||
def mtime
|
||||
modified_time.to_i
|
||||
end
|
||||
|
||||
# Is source path modified?
|
||||
#
|
||||
# Returns true if modified since last write.
|
||||
def modified?
|
||||
self.class.mtimes[path] != mtime
|
||||
end
|
||||
|
||||
# Whether to write the file to the filesystem
|
||||
#
|
||||
# Returns true unless the defaults for the destination path from
|
||||
# _config.yml contain `published: false`.
|
||||
def write?
|
||||
publishable = defaults.fetch("published", true)
|
||||
return publishable unless @collection
|
||||
|
||||
publishable && @collection.write?
|
||||
end
|
||||
|
||||
# Write the static file to the destination directory (if modified).
|
||||
#
|
||||
# dest - The String path to the destination dir.
|
||||
#
|
||||
# Returns false if the file was not modified since last time (no-op).
|
||||
def write(dest)
|
||||
dest_path = destination(dest)
|
||||
return false if File.exist?(dest_path) && !modified?
|
||||
|
||||
self.class.mtimes[path] = mtime
|
||||
|
||||
FileUtils.mkdir_p(File.dirname(dest_path))
|
||||
FileUtils.rm(dest_path) if File.exist?(dest_path)
|
||||
copy_file(dest_path)
|
||||
|
||||
true
|
||||
end
|
||||
|
||||
def data
|
||||
@data ||= @site.frontmatter_defaults.all(relative_path, type)
|
||||
end
|
||||
|
||||
def to_liquid
|
||||
@to_liquid ||= Drops::StaticFileDrop.new(self)
|
||||
end
|
||||
|
||||
# Generate "basename without extension" and strip away any trailing periods.
|
||||
# NOTE: `String#gsub` removes all trailing periods (in comparison to `String#chomp`)
|
||||
def basename
|
||||
@basename ||= File.basename(name, extname).gsub(%r!\.*\z!, "")
|
||||
end
|
||||
|
||||
def placeholders
|
||||
{
|
||||
:collection => @collection.label,
|
||||
:path => cleaned_relative_path,
|
||||
:output_ext => "",
|
||||
:name => basename,
|
||||
:title => "",
|
||||
}
|
||||
end
|
||||
|
||||
# Similar to Jekyll::Document#cleaned_relative_path.
|
||||
# Generates a relative path with the collection's directory removed when applicable
|
||||
# and additionally removes any multiple periods in the string.
|
||||
#
|
||||
# NOTE: `String#gsub!` removes all trailing periods (in comparison to `String#chomp!`)
|
||||
#
|
||||
# Examples:
|
||||
# When `relative_path` is "_methods/site/my-cool-avatar...png":
|
||||
# cleaned_relative_path
|
||||
# # => "/site/my-cool-avatar"
|
||||
#
|
||||
# Returns the cleaned relative path of the static file.
|
||||
def cleaned_relative_path
|
||||
@cleaned_relative_path ||= begin
|
||||
cleaned = relative_path[0..-extname.length - 1]
|
||||
cleaned.gsub!(%r!\.*\z!, "")
|
||||
cleaned.sub!(@collection.relative_directory, "") if @collection
|
||||
cleaned
|
||||
end
|
||||
end
|
||||
|
||||
# Applies a similar URL-building technique as Jekyll::Document that takes
|
||||
# the collection's URL template into account. The default URL template can
|
||||
# be overriden in the collection's configuration in _config.yml.
|
||||
def url
|
||||
@url ||= begin
|
||||
base = if @collection.nil?
|
||||
cleaned_relative_path
|
||||
else
|
||||
Jekyll::URL.new(
|
||||
:template => @collection.url_template,
|
||||
:placeholders => placeholders
|
||||
)
|
||||
end.to_s.chomp("/")
|
||||
base << extname
|
||||
end
|
||||
end
|
||||
|
||||
# Returns the type of the collection if present, nil otherwise.
|
||||
def type
|
||||
@type ||= @collection.nil? ? nil : @collection.label.to_sym
|
||||
end
|
||||
|
||||
# Returns the front matter defaults defined for the file's URL and/or type
|
||||
# as defined in _config.yml.
|
||||
def defaults
|
||||
@defaults ||= @site.frontmatter_defaults.all url, type
|
||||
end
|
||||
|
||||
# Returns a debug string on inspecting the static file.
|
||||
# Includes only the relative path of the object.
|
||||
def inspect
|
||||
"#<#{self.class} @relative_path=#{relative_path.inspect}>"
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def copy_file(dest_path)
|
||||
if @site.safe || Jekyll.env == "production"
|
||||
FileUtils.cp(path, dest_path)
|
||||
else
|
||||
FileUtils.copy_entry(path, dest_path)
|
||||
end
|
||||
|
||||
unless File.symlink?(dest_path)
|
||||
File.utime(self.class.mtimes[path], self.class.mtimes[path], dest_path)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
60
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/stevenson.rb
vendored
Normal file
60
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/stevenson.rb
vendored
Normal file
@@ -0,0 +1,60 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Jekyll
|
||||
class Stevenson < ::Logger
|
||||
def initialize
|
||||
@progname = nil
|
||||
@level = DEBUG
|
||||
@default_formatter = Formatter.new
|
||||
@logdev = $stdout
|
||||
@formatter = proc do |_, _, _, msg|
|
||||
msg.to_s
|
||||
end
|
||||
end
|
||||
|
||||
def add(severity, message = nil, progname = nil)
|
||||
severity ||= UNKNOWN
|
||||
@logdev = logdevice(severity)
|
||||
|
||||
return true if @logdev.nil? || severity < @level
|
||||
|
||||
progname ||= @progname
|
||||
if message.nil?
|
||||
if block_given?
|
||||
message = yield
|
||||
else
|
||||
message = progname
|
||||
progname = @progname
|
||||
end
|
||||
end
|
||||
@logdev.puts(
|
||||
format_message(format_severity(severity), Time.now, progname, message)
|
||||
)
|
||||
true
|
||||
end
|
||||
|
||||
# Log a +WARN+ message
|
||||
def warn(progname = nil, &block)
|
||||
add(WARN, nil, progname.yellow, &block)
|
||||
end
|
||||
|
||||
# Log an +ERROR+ message
|
||||
def error(progname = nil, &block)
|
||||
add(ERROR, nil, progname.red, &block)
|
||||
end
|
||||
|
||||
def close
|
||||
# No LogDevice in use
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def logdevice(severity)
|
||||
if severity > INFO
|
||||
$stderr
|
||||
else
|
||||
$stdout
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
110
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/tags/highlight.rb
vendored
Normal file
110
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/tags/highlight.rb
vendored
Normal file
@@ -0,0 +1,110 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Jekyll
|
||||
module Tags
|
||||
class HighlightBlock < Liquid::Block
|
||||
include Liquid::StandardFilters
|
||||
|
||||
# The regular expression syntax checker. Start with the language specifier.
|
||||
# Follow that by zero or more space separated options that take one of three
|
||||
# forms: name, name=value, or name="<quoted list>"
|
||||
#
|
||||
# <quoted list> is a space-separated list of numbers
|
||||
SYNTAX = %r!^([a-zA-Z0-9.+#_-]+)((\s+\w+(=(\w+|"([0-9]+\s)*[0-9]+"))?)*)$!.freeze
|
||||
|
||||
def initialize(tag_name, markup, tokens)
|
||||
super
|
||||
if markup.strip =~ SYNTAX
|
||||
@lang = Regexp.last_match(1).downcase
|
||||
@highlight_options = parse_options(Regexp.last_match(2))
|
||||
else
|
||||
raise SyntaxError, <<~MSG
|
||||
Syntax Error in tag 'highlight' while parsing the following markup:
|
||||
|
||||
#{markup}
|
||||
|
||||
Valid syntax: highlight <lang> [linenos]
|
||||
MSG
|
||||
end
|
||||
end
|
||||
|
||||
LEADING_OR_TRAILING_LINE_TERMINATORS = %r!\A(\n|\r)+|(\n|\r)+\z!.freeze
|
||||
|
||||
def render(context)
|
||||
prefix = context["highlighter_prefix"] || ""
|
||||
suffix = context["highlighter_suffix"] || ""
|
||||
code = super.to_s.gsub(LEADING_OR_TRAILING_LINE_TERMINATORS, "")
|
||||
|
||||
output =
|
||||
case context.registers[:site].highlighter
|
||||
when "rouge"
|
||||
render_rouge(code)
|
||||
when "pygments"
|
||||
render_pygments(code, context)
|
||||
else
|
||||
render_codehighlighter(code)
|
||||
end
|
||||
|
||||
rendered_output = add_code_tag(output)
|
||||
prefix + rendered_output + suffix
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
OPTIONS_REGEX = %r!(?:\w="[^"]*"|\w=\w|\w)+!.freeze
|
||||
|
||||
def parse_options(input)
|
||||
options = {}
|
||||
return options if input.empty?
|
||||
|
||||
# Split along 3 possible forms -- key="<quoted list>", key=value, or key
|
||||
input.scan(OPTIONS_REGEX) do |opt|
|
||||
key, value = opt.split("=")
|
||||
# If a quoted list, convert to array
|
||||
if value&.include?('"')
|
||||
value.delete!('"')
|
||||
value = value.split
|
||||
end
|
||||
options[key.to_sym] = value || true
|
||||
end
|
||||
|
||||
options[:linenos] = "inline" if options[:linenos] == true
|
||||
options
|
||||
end
|
||||
|
||||
def render_pygments(code, _context)
|
||||
Jekyll.logger.warn "Warning:", "Highlight Tag no longer supports rendering with Pygments."
|
||||
Jekyll.logger.warn "", "Using the default highlighter, Rouge, instead."
|
||||
render_rouge(code)
|
||||
end
|
||||
|
||||
def render_rouge(code)
|
||||
require "rouge"
|
||||
formatter = ::Rouge::Formatters::HTMLLegacy.new(
|
||||
:line_numbers => @highlight_options[:linenos],
|
||||
:wrap => false,
|
||||
:css_class => "highlight",
|
||||
:gutter_class => "gutter",
|
||||
:code_class => "code"
|
||||
)
|
||||
lexer = ::Rouge::Lexer.find_fancy(@lang, code) || Rouge::Lexers::PlainText
|
||||
formatter.format(lexer.lex(code))
|
||||
end
|
||||
|
||||
def render_codehighlighter(code)
|
||||
h(code).strip
|
||||
end
|
||||
|
||||
def add_code_tag(code)
|
||||
code_attributes = [
|
||||
"class=\"language-#{@lang.to_s.tr("+", "-")}\"",
|
||||
"data-lang=\"#{@lang}\"",
|
||||
].join(" ")
|
||||
"<figure class=\"highlight\"><pre><code #{code_attributes}>"\
|
||||
"#{code.chomp}</code></pre></figure>"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Liquid::Template.register_tag("highlight", Jekyll::Tags::HighlightBlock)
|
||||
270
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/tags/include.rb
vendored
Normal file
270
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/tags/include.rb
vendored
Normal file
@@ -0,0 +1,270 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Jekyll
|
||||
module Tags
|
||||
class IncludeTag < Liquid::Tag
|
||||
VALID_SYNTAX = %r!
|
||||
([\w-]+)\s*=\s*
|
||||
(?:"([^"\\]*(?:\\.[^"\\]*)*)"|'([^'\\]*(?:\\.[^'\\]*)*)'|([\w.-]+))
|
||||
!x.freeze
|
||||
VARIABLE_SYNTAX = %r!
|
||||
(?<variable>[^{]*(\{\{\s*[\w\-.]+\s*(\|.*)?\}\}[^\s{}]*)+)
|
||||
(?<params>.*)
|
||||
!mx.freeze
|
||||
|
||||
FULL_VALID_SYNTAX = %r!\A\s*(?:#{VALID_SYNTAX}(?=\s|\z)\s*)*\z!.freeze
|
||||
VALID_FILENAME_CHARS = %r!^[\w/.-]+$!.freeze
|
||||
INVALID_SEQUENCES = %r![./]{2,}!.freeze
|
||||
|
||||
def initialize(tag_name, markup, tokens)
|
||||
super
|
||||
markup = markup.strip
|
||||
matched = markup.match(VARIABLE_SYNTAX)
|
||||
if matched
|
||||
@file = matched["variable"].strip
|
||||
@params = matched["params"].strip
|
||||
else
|
||||
@file, @params = markup.split(%r!\s+!, 2)
|
||||
end
|
||||
validate_params if @params
|
||||
@tag_name = tag_name
|
||||
end
|
||||
|
||||
def syntax_example
|
||||
"{% #{@tag_name} file.ext param='value' param2='value' %}"
|
||||
end
|
||||
|
||||
def parse_params(context)
|
||||
params = {}
|
||||
@params.scan(VALID_SYNTAX) do |key, d_quoted, s_quoted, variable|
|
||||
value = if d_quoted
|
||||
d_quoted.include?('\\"') ? d_quoted.gsub('\\"', '"') : d_quoted
|
||||
elsif s_quoted
|
||||
s_quoted.include?("\\'") ? s_quoted.gsub("\\'", "'") : s_quoted
|
||||
elsif variable
|
||||
context[variable]
|
||||
end
|
||||
|
||||
params[key] = value
|
||||
end
|
||||
params
|
||||
end
|
||||
|
||||
def validate_file_name(file)
|
||||
if INVALID_SEQUENCES.match?(file) || !VALID_FILENAME_CHARS.match?(file)
|
||||
raise ArgumentError, <<~MSG
|
||||
Invalid syntax for include tag. File contains invalid characters or sequences:
|
||||
|
||||
#{file}
|
||||
|
||||
Valid syntax:
|
||||
|
||||
#{syntax_example}
|
||||
|
||||
MSG
|
||||
end
|
||||
end
|
||||
|
||||
def validate_params
|
||||
unless FULL_VALID_SYNTAX.match?(@params)
|
||||
raise ArgumentError, <<~MSG
|
||||
Invalid syntax for include tag:
|
||||
|
||||
#{@params}
|
||||
|
||||
Valid syntax:
|
||||
|
||||
#{syntax_example}
|
||||
|
||||
MSG
|
||||
end
|
||||
end
|
||||
|
||||
# Grab file read opts in the context
|
||||
def file_read_opts(context)
|
||||
context.registers[:site].file_read_opts
|
||||
end
|
||||
|
||||
# Render the variable if required
|
||||
def render_variable(context)
|
||||
Liquid::Template.parse(@file).render(context) if VARIABLE_SYNTAX.match?(@file)
|
||||
end
|
||||
|
||||
def tag_includes_dirs(context)
|
||||
context.registers[:site].includes_load_paths.freeze
|
||||
end
|
||||
|
||||
def locate_include_file(context, file, safe)
|
||||
includes_dirs = tag_includes_dirs(context)
|
||||
includes_dirs.each do |dir|
|
||||
path = PathManager.join(dir, file)
|
||||
return path if valid_include_file?(path, dir.to_s, safe)
|
||||
end
|
||||
raise IOError, could_not_locate_message(file, includes_dirs, safe)
|
||||
end
|
||||
|
||||
def render(context)
|
||||
site = context.registers[:site]
|
||||
|
||||
file = render_variable(context) || @file
|
||||
validate_file_name(file)
|
||||
|
||||
path = locate_include_file(context, file, site.safe)
|
||||
return unless path
|
||||
|
||||
add_include_to_dependency(site, path, context)
|
||||
|
||||
partial = load_cached_partial(path, context)
|
||||
|
||||
context.stack do
|
||||
context["include"] = parse_params(context) if @params
|
||||
begin
|
||||
partial.render!(context)
|
||||
rescue Liquid::Error => e
|
||||
e.template_name = path
|
||||
e.markup_context = "included " if e.markup_context.nil?
|
||||
raise e
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def add_include_to_dependency(site, path, context)
|
||||
if context.registers[:page]&.key?("path")
|
||||
site.regenerator.add_dependency(
|
||||
site.in_source_dir(context.registers[:page]["path"]),
|
||||
path
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
def load_cached_partial(path, context)
|
||||
context.registers[:cached_partials] ||= {}
|
||||
cached_partial = context.registers[:cached_partials]
|
||||
|
||||
if cached_partial.key?(path)
|
||||
cached_partial[path]
|
||||
else
|
||||
unparsed_file = context.registers[:site]
|
||||
.liquid_renderer
|
||||
.file(path)
|
||||
begin
|
||||
cached_partial[path] = unparsed_file.parse(read_file(path, context))
|
||||
rescue Liquid::Error => e
|
||||
e.template_name = path
|
||||
e.markup_context = "included " if e.markup_context.nil?
|
||||
raise e
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def valid_include_file?(path, dir, safe)
|
||||
!outside_site_source?(path, dir, safe) && File.file?(path)
|
||||
end
|
||||
|
||||
def outside_site_source?(path, dir, safe)
|
||||
safe && !realpath_prefixed_with?(path, dir)
|
||||
end
|
||||
|
||||
def realpath_prefixed_with?(path, dir)
|
||||
File.exist?(path) && File.realpath(path).start_with?(dir)
|
||||
rescue StandardError
|
||||
false
|
||||
end
|
||||
|
||||
# This method allows to modify the file content by inheriting from the class.
|
||||
def read_file(file, context)
|
||||
File.read(file, **file_read_opts(context))
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def could_not_locate_message(file, includes_dirs, safe)
|
||||
message = "Could not locate the included file '#{file}' in any of "\
|
||||
"#{includes_dirs}. Ensure it exists in one of those directories and"
|
||||
message + if safe
|
||||
" is not a symlink as those are not allowed in safe mode."
|
||||
else
|
||||
", if it is a symlink, does not point outside your site source."
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Do not inherit from this class.
|
||||
# TODO: Merge into the `Jekyll::Tags::IncludeTag` in v5.0
|
||||
class OptimizedIncludeTag < IncludeTag
|
||||
def render(context)
|
||||
@site ||= context.registers[:site]
|
||||
|
||||
file = render_variable(context) || @file
|
||||
validate_file_name(file)
|
||||
|
||||
@site.inclusions[file] ||= locate_include_file(file)
|
||||
inclusion = @site.inclusions[file]
|
||||
|
||||
add_include_to_dependency(inclusion, context) if @site.config["incremental"]
|
||||
|
||||
context.stack do
|
||||
context["include"] = parse_params(context) if @params
|
||||
inclusion.render(context)
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def locate_include_file(file)
|
||||
@site.includes_load_paths.each do |dir|
|
||||
path = PathManager.join(dir, file)
|
||||
return Inclusion.new(@site, dir, file) if valid_include_file?(path, dir)
|
||||
end
|
||||
raise IOError, could_not_locate_message(file, @site.includes_load_paths, @site.safe)
|
||||
end
|
||||
|
||||
def valid_include_file?(path, dir)
|
||||
File.file?(path) && !outside_scope?(path, dir)
|
||||
end
|
||||
|
||||
def outside_scope?(path, dir)
|
||||
@site.safe && !realpath_prefixed_with?(path, dir)
|
||||
end
|
||||
|
||||
def realpath_prefixed_with?(path, dir)
|
||||
File.realpath(path).start_with?(dir)
|
||||
rescue StandardError
|
||||
false
|
||||
end
|
||||
|
||||
def add_include_to_dependency(inclusion, context)
|
||||
return unless context.registers[:page]&.key?("path")
|
||||
|
||||
@site.regenerator.add_dependency(
|
||||
@site.in_source_dir(context.registers[:page]["path"]),
|
||||
inclusion.path
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
class IncludeRelativeTag < IncludeTag
|
||||
def tag_includes_dirs(context)
|
||||
Array(page_path(context)).freeze
|
||||
end
|
||||
|
||||
def page_path(context)
|
||||
page, site = context.registers.values_at(:page, :site)
|
||||
return site.source unless page
|
||||
|
||||
site.in_source_dir File.dirname(resource_path(page, site))
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def resource_path(page, site)
|
||||
path = page["path"]
|
||||
path = File.join(site.config["collections_dir"], path) if page["collection"]
|
||||
path.sub(%r!/#excerpt\z!, "")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Liquid::Template.register_tag("include", Jekyll::Tags::OptimizedIncludeTag)
|
||||
Liquid::Template.register_tag("include_relative", Jekyll::Tags::IncludeRelativeTag)
|
||||
42
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/tags/link.rb
vendored
Normal file
42
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/tags/link.rb
vendored
Normal file
@@ -0,0 +1,42 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Jekyll
|
||||
module Tags
|
||||
class Link < Liquid::Tag
|
||||
include Jekyll::Filters::URLFilters
|
||||
|
||||
class << self
|
||||
def tag_name
|
||||
name.split("::").last.downcase
|
||||
end
|
||||
end
|
||||
|
||||
def initialize(tag_name, relative_path, tokens)
|
||||
super
|
||||
|
||||
@relative_path = relative_path.strip
|
||||
end
|
||||
|
||||
def render(context)
|
||||
@context = context
|
||||
site = context.registers[:site]
|
||||
relative_path = Liquid::Template.parse(@relative_path).render(context)
|
||||
relative_path_with_leading_slash = PathManager.join("", relative_path)
|
||||
|
||||
site.each_site_file do |item|
|
||||
return relative_url(item) if item.relative_path == relative_path
|
||||
# This takes care of the case for static files that have a leading /
|
||||
return relative_url(item) if item.relative_path == relative_path_with_leading_slash
|
||||
end
|
||||
|
||||
raise ArgumentError, <<~MSG
|
||||
Could not find document '#{relative_path}' in tag '#{self.class.tag_name}'.
|
||||
|
||||
Make sure the document exists and the path is correct.
|
||||
MSG
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Liquid::Template.register_tag(Jekyll::Tags::Link.tag_name, Jekyll::Tags::Link)
|
||||
106
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/tags/post_url.rb
vendored
Normal file
106
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/tags/post_url.rb
vendored
Normal file
@@ -0,0 +1,106 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Jekyll
|
||||
module Tags
|
||||
class PostComparer
|
||||
MATCHER = %r!^(.+/)*(\d+-\d+-\d+)-(.*)$!.freeze
|
||||
|
||||
attr_reader :path, :date, :slug, :name
|
||||
|
||||
def initialize(name)
|
||||
@name = name
|
||||
|
||||
all, @path, @date, @slug = *name.sub(%r!^/!, "").match(MATCHER)
|
||||
unless all
|
||||
raise Jekyll::Errors::InvalidPostNameError,
|
||||
"'#{name}' does not contain valid date and/or title."
|
||||
end
|
||||
|
||||
basename_pattern = "#{date}-#{Regexp.escape(slug)}\\.[^.]+"
|
||||
@name_regex = %r!^_posts/#{path}#{basename_pattern}|^#{path}_posts/?#{basename_pattern}!
|
||||
end
|
||||
|
||||
def post_date
|
||||
@post_date ||= Utils.parse_date(
|
||||
date,
|
||||
"'#{date}' does not contain valid date and/or title."
|
||||
)
|
||||
end
|
||||
|
||||
def ==(other)
|
||||
other.relative_path.match(@name_regex)
|
||||
end
|
||||
|
||||
def deprecated_equality(other)
|
||||
slug == post_slug(other) &&
|
||||
post_date.year == other.date.year &&
|
||||
post_date.month == other.date.month &&
|
||||
post_date.day == other.date.day
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# Construct the directory-aware post slug for a Jekyll::Post
|
||||
#
|
||||
# other - the Jekyll::Post
|
||||
#
|
||||
# Returns the post slug with the subdirectory (relative to _posts)
|
||||
def post_slug(other)
|
||||
path = other.basename.split("/")[0...-1].join("/")
|
||||
if path.nil? || path == ""
|
||||
other.data["slug"]
|
||||
else
|
||||
"#{path}/#{other.data["slug"]}"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
class PostUrl < Liquid::Tag
|
||||
include Jekyll::Filters::URLFilters
|
||||
|
||||
def initialize(tag_name, post, tokens)
|
||||
super
|
||||
@orig_post = post.strip
|
||||
begin
|
||||
@post = PostComparer.new(@orig_post)
|
||||
rescue StandardError => e
|
||||
raise Jekyll::Errors::PostURLError, <<~MSG
|
||||
Could not parse name of post "#{@orig_post}" in tag 'post_url'.
|
||||
Make sure the post exists and the name is correct.
|
||||
#{e.class}: #{e.message}
|
||||
MSG
|
||||
end
|
||||
end
|
||||
|
||||
def render(context)
|
||||
@context = context
|
||||
site = context.registers[:site]
|
||||
|
||||
site.posts.docs.each do |document|
|
||||
return relative_url(document) if @post == document
|
||||
end
|
||||
|
||||
# New matching method did not match, fall back to old method
|
||||
# with deprecation warning if this matches
|
||||
|
||||
site.posts.docs.each do |document|
|
||||
next unless @post.deprecated_equality document
|
||||
|
||||
Jekyll::Deprecator.deprecation_message "A call to "\
|
||||
"'{% post_url #{@post.name} %}' did not match " \
|
||||
"a post using the new matching method of checking name " \
|
||||
"(path-date-slug) equality. Please make sure that you " \
|
||||
"change this tag to match the post's name exactly."
|
||||
return relative_url(document)
|
||||
end
|
||||
|
||||
raise Jekyll::Errors::PostURLError, <<~MSG
|
||||
Could not find post "#{@orig_post}" in tag 'post_url'.
|
||||
Make sure the post exists and the name is correct.
|
||||
MSG
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Liquid::Template.register_tag("post_url", Jekyll::Tags::PostUrl)
|
||||
86
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/theme.rb
vendored
Normal file
86
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/theme.rb
vendored
Normal file
@@ -0,0 +1,86 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Jekyll
|
||||
class Theme
|
||||
extend Forwardable
|
||||
attr_reader :name
|
||||
|
||||
def_delegator :gemspec, :version, :version
|
||||
|
||||
def initialize(name)
|
||||
@name = name.downcase.strip
|
||||
Jekyll.logger.debug "Theme:", name
|
||||
Jekyll.logger.debug "Theme source:", root
|
||||
end
|
||||
|
||||
def root
|
||||
# Must use File.realpath to resolve symlinks created by rbenv
|
||||
# Otherwise, Jekyll.sanitized path with prepend the unresolved root
|
||||
@root ||= File.realpath(gemspec.full_gem_path)
|
||||
rescue Errno::ENOENT, Errno::EACCES, Errno::ELOOP
|
||||
raise "Path #{gemspec.full_gem_path} does not exist, is not accessible "\
|
||||
"or includes a symbolic link loop"
|
||||
end
|
||||
|
||||
# The name of theme directory
|
||||
def basename
|
||||
@basename ||= File.basename(root)
|
||||
end
|
||||
|
||||
def includes_path
|
||||
@includes_path ||= path_for "_includes"
|
||||
end
|
||||
|
||||
def layouts_path
|
||||
@layouts_path ||= path_for "_layouts"
|
||||
end
|
||||
|
||||
def sass_path
|
||||
@sass_path ||= path_for "_sass"
|
||||
end
|
||||
|
||||
def assets_path
|
||||
@assets_path ||= path_for "assets"
|
||||
end
|
||||
|
||||
def runtime_dependencies
|
||||
gemspec.runtime_dependencies
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def path_for(folder)
|
||||
path = realpath_for(folder)
|
||||
path if path && File.directory?(path)
|
||||
end
|
||||
|
||||
def realpath_for(folder)
|
||||
# This resolves all symlinks for the theme subfolder and then ensures that the directory
|
||||
# remains inside the theme root. This prevents the use of symlinks for theme subfolders to
|
||||
# escape the theme root.
|
||||
# However, symlinks are allowed to point to other directories within the theme.
|
||||
Jekyll.sanitized_path(root, File.realpath(Jekyll.sanitized_path(root, folder.to_s)))
|
||||
rescue Errno::ENOENT, Errno::EACCES, Errno::ELOOP => e
|
||||
log_realpath_exception(e, folder)
|
||||
nil
|
||||
end
|
||||
|
||||
def log_realpath_exception(err, folder)
|
||||
return if err.is_a?(Errno::ENOENT)
|
||||
|
||||
case err
|
||||
when Errno::EACCES
|
||||
Jekyll.logger.error "Theme error:", "Directory '#{folder}' is not accessible."
|
||||
when Errno::ELOOP
|
||||
Jekyll.logger.error "Theme error:", "Directory '#{folder}' includes a symbolic link loop."
|
||||
end
|
||||
end
|
||||
|
||||
def gemspec
|
||||
@gemspec ||= Gem::Specification.find_by_name(name)
|
||||
rescue Gem::LoadError
|
||||
raise Jekyll::Errors::MissingDependencyException,
|
||||
"The #{name} theme could not be found."
|
||||
end
|
||||
end
|
||||
end
|
||||
121
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/theme_builder.rb
vendored
Normal file
121
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/theme_builder.rb
vendored
Normal file
@@ -0,0 +1,121 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Jekyll
|
||||
class ThemeBuilder
|
||||
SCAFFOLD_DIRECTORIES = %w(
|
||||
assets _layouts _includes _sass
|
||||
).freeze
|
||||
|
||||
attr_reader :name, :path, :code_of_conduct
|
||||
|
||||
def initialize(theme_name, opts)
|
||||
@name = theme_name.to_s.tr(" ", "_").squeeze("_")
|
||||
@path = Pathname.new(File.expand_path(name, Dir.pwd))
|
||||
@code_of_conduct = !!opts["code_of_conduct"]
|
||||
end
|
||||
|
||||
def create!
|
||||
create_directories
|
||||
create_starter_files
|
||||
create_gemspec
|
||||
create_accessories
|
||||
initialize_git_repo
|
||||
end
|
||||
|
||||
def user_name
|
||||
@user_name ||= `git config user.name`.chomp
|
||||
end
|
||||
|
||||
def user_email
|
||||
@user_email ||= `git config user.email`.chomp
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def root
|
||||
@root ||= Pathname.new(File.expand_path("../", __dir__))
|
||||
end
|
||||
|
||||
def template_file(filename)
|
||||
[
|
||||
root.join("theme_template", "#{filename}.erb"),
|
||||
root.join("theme_template", filename.to_s),
|
||||
].find(&:exist?)
|
||||
end
|
||||
|
||||
def template(filename)
|
||||
erb.render(template_file(filename).read)
|
||||
end
|
||||
|
||||
def erb
|
||||
@erb ||= ERBRenderer.new(self)
|
||||
end
|
||||
|
||||
def mkdir_p(directories)
|
||||
Array(directories).each do |directory|
|
||||
full_path = path.join(directory)
|
||||
Jekyll.logger.info "create", full_path.to_s
|
||||
FileUtils.mkdir_p(full_path)
|
||||
end
|
||||
end
|
||||
|
||||
def write_file(filename, contents)
|
||||
full_path = path.join(filename)
|
||||
Jekyll.logger.info "create", full_path.to_s
|
||||
File.write(full_path, contents)
|
||||
end
|
||||
|
||||
def create_directories
|
||||
mkdir_p(SCAFFOLD_DIRECTORIES)
|
||||
end
|
||||
|
||||
def create_starter_files
|
||||
%w(page post default).each do |layout|
|
||||
write_file("_layouts/#{layout}.html", template("_layouts/#{layout}.html"))
|
||||
end
|
||||
end
|
||||
|
||||
def create_gemspec
|
||||
write_file("Gemfile", template("Gemfile"))
|
||||
write_file("#{name}.gemspec", template("theme.gemspec"))
|
||||
end
|
||||
|
||||
def create_accessories
|
||||
accessories = %w(README.md LICENSE.txt)
|
||||
accessories << "CODE_OF_CONDUCT.md" if code_of_conduct
|
||||
accessories.each do |filename|
|
||||
write_file(filename, template(filename))
|
||||
end
|
||||
end
|
||||
|
||||
def initialize_git_repo
|
||||
Jekyll.logger.info "initialize", path.join(".git").to_s
|
||||
Dir.chdir(path.to_s) { `git init` }
|
||||
write_file(".gitignore", template("gitignore"))
|
||||
end
|
||||
|
||||
class ERBRenderer
|
||||
extend Forwardable
|
||||
|
||||
def_delegator :@theme_builder, :name, :theme_name
|
||||
def_delegator :@theme_builder, :user_name, :user_name
|
||||
def_delegator :@theme_builder, :user_email, :user_email
|
||||
|
||||
def initialize(theme_builder)
|
||||
@theme_builder = theme_builder
|
||||
end
|
||||
|
||||
def jekyll_version_with_minor
|
||||
Jekyll::VERSION.split(".").take(2).join(".")
|
||||
end
|
||||
|
||||
def theme_directories
|
||||
SCAFFOLD_DIRECTORIES
|
||||
end
|
||||
|
||||
def render(contents)
|
||||
ERB.new(contents).result binding
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
167
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/url.rb
vendored
Normal file
167
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/url.rb
vendored
Normal file
@@ -0,0 +1,167 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
# Public: Methods that generate a URL for a resource such as a Post or a Page.
|
||||
#
|
||||
# Examples
|
||||
#
|
||||
# URL.new({
|
||||
# :template => /:categories/:title.html",
|
||||
# :placeholders => {:categories => "ruby", :title => "something"}
|
||||
# }).to_s
|
||||
#
|
||||
module Jekyll
|
||||
class URL
|
||||
# options - One of :permalink or :template must be supplied.
|
||||
# :template - The String used as template for URL generation,
|
||||
# for example "/:path/:basename:output_ext", where
|
||||
# a placeholder is prefixed with a colon.
|
||||
# :placeholders - A hash containing the placeholders which will be
|
||||
# replaced when used inside the template. E.g.
|
||||
# { "year" => Time.now.strftime("%Y") } would replace
|
||||
# the placeholder ":year" with the current year.
|
||||
# :permalink - If supplied, no URL will be generated from the
|
||||
# template. Instead, the given permalink will be
|
||||
# used as URL.
|
||||
def initialize(options)
|
||||
@template = options[:template]
|
||||
@placeholders = options[:placeholders] || {}
|
||||
@permalink = options[:permalink]
|
||||
|
||||
if (@template || @permalink).nil?
|
||||
raise ArgumentError, "One of :template or :permalink must be supplied."
|
||||
end
|
||||
end
|
||||
|
||||
# The generated relative URL of the resource
|
||||
#
|
||||
# Returns the String URL
|
||||
def to_s
|
||||
sanitize_url(generated_permalink || generated_url)
|
||||
end
|
||||
|
||||
# Generates a URL from the permalink
|
||||
#
|
||||
# Returns the _unsanitized String URL
|
||||
def generated_permalink
|
||||
(@generated_permalink ||= generate_url(@permalink)) if @permalink
|
||||
end
|
||||
|
||||
# Generates a URL from the template
|
||||
#
|
||||
# Returns the unsanitized String URL
|
||||
def generated_url
|
||||
@generated_url ||= generate_url(@template)
|
||||
end
|
||||
|
||||
# Internal: Generate the URL by replacing all placeholders with their
|
||||
# respective values in the given template
|
||||
#
|
||||
# Returns the unsanitized String URL
|
||||
def generate_url(template)
|
||||
if @placeholders.is_a? Drops::UrlDrop
|
||||
generate_url_from_drop(template)
|
||||
else
|
||||
generate_url_from_hash(template)
|
||||
end
|
||||
end
|
||||
|
||||
def generate_url_from_hash(template)
|
||||
@placeholders.inject(template) do |result, token|
|
||||
break result if result.index(":").nil?
|
||||
|
||||
if token.last.nil?
|
||||
# Remove leading "/" to avoid generating urls with `//`
|
||||
result.gsub("/:#{token.first}", "")
|
||||
else
|
||||
result.gsub(":#{token.first}", self.class.escape_path(token.last))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# We include underscores in keys to allow for 'i_month' and so forth.
|
||||
# This poses a problem for keys which are followed by an underscore
|
||||
# but the underscore is not part of the key, e.g. '/:month_:day'.
|
||||
# That should be :month and :day, but our key extraction regexp isn't
|
||||
# smart enough to know that so we have to make it an explicit
|
||||
# possibility.
|
||||
def possible_keys(key)
|
||||
if key.end_with?("_")
|
||||
[key, key.chomp("_")]
|
||||
else
|
||||
[key]
|
||||
end
|
||||
end
|
||||
|
||||
def generate_url_from_drop(template)
|
||||
template.gsub(%r!:([a-z_]+)!) do |match|
|
||||
name = Regexp.last_match(1)
|
||||
pool = name.end_with?("_") ? [name, name.chomp!("_")] : [name]
|
||||
|
||||
winner = pool.find { |key| @placeholders.key?(key) }
|
||||
if winner.nil?
|
||||
raise NoMethodError,
|
||||
"The URL template doesn't have #{pool.join(" or ")} keys. "\
|
||||
"Check your permalink template!"
|
||||
end
|
||||
|
||||
value = @placeholders[winner]
|
||||
value = "" if value.nil?
|
||||
replacement = self.class.escape_path(value)
|
||||
|
||||
match.sub!(":#{winner}", replacement)
|
||||
end
|
||||
end
|
||||
|
||||
# Returns a sanitized String URL, stripping "../../" and multiples of "/",
|
||||
# as well as the beginning "/" so we can enforce and ensure it.
|
||||
def sanitize_url(str)
|
||||
"/#{str}".gsub("..", "/").tap do |result|
|
||||
result.gsub!("./", "")
|
||||
result.squeeze!("/")
|
||||
end
|
||||
end
|
||||
|
||||
# Escapes a path to be a valid URL path segment
|
||||
#
|
||||
# path - The path to be escaped.
|
||||
#
|
||||
# Examples:
|
||||
#
|
||||
# URL.escape_path("/a b")
|
||||
# # => "/a%20b"
|
||||
#
|
||||
# Returns the escaped path.
|
||||
def self.escape_path(path)
|
||||
return path if path.empty? || %r!^[a-zA-Z0-9./-]+$!.match?(path)
|
||||
|
||||
# Because URI.escape doesn't escape "?", "[" and "]" by default,
|
||||
# specify unsafe string (except unreserved, sub-delims, ":", "@" and "/").
|
||||
#
|
||||
# URI path segment is defined in RFC 3986 as follows:
|
||||
# segment = *pchar
|
||||
# pchar = unreserved / pct-encoded / sub-delims / ":" / "@"
|
||||
# unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
|
||||
# pct-encoded = "%" HEXDIG HEXDIG
|
||||
# sub-delims = "!" / "$" / "&" / "'" / "(" / ")"
|
||||
# / "*" / "+" / "," / ";" / "="
|
||||
Addressable::URI.encode(path).encode("utf-8").sub("#", "%23")
|
||||
end
|
||||
|
||||
# Unescapes a URL path segment
|
||||
#
|
||||
# path - The path to be unescaped.
|
||||
#
|
||||
# Examples:
|
||||
#
|
||||
# URL.unescape_path("/a%20b")
|
||||
# # => "/a b"
|
||||
#
|
||||
# Returns the unescaped path.
|
||||
def self.unescape_path(path)
|
||||
path = path.encode("utf-8")
|
||||
return path unless path.include?("%")
|
||||
|
||||
Addressable::URI.unencode(path)
|
||||
end
|
||||
end
|
||||
end
|
||||
367
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/utils.rb
vendored
Normal file
367
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/utils.rb
vendored
Normal file
@@ -0,0 +1,367 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Jekyll
|
||||
module Utils
|
||||
extend self
|
||||
autoload :Ansi, "jekyll/utils/ansi"
|
||||
autoload :Exec, "jekyll/utils/exec"
|
||||
autoload :Internet, "jekyll/utils/internet"
|
||||
autoload :Platforms, "jekyll/utils/platforms"
|
||||
autoload :ThreadEvent, "jekyll/utils/thread_event"
|
||||
autoload :WinTZ, "jekyll/utils/win_tz"
|
||||
|
||||
# Constants for use in #slugify
|
||||
SLUGIFY_MODES = %w(raw default pretty ascii latin).freeze
|
||||
SLUGIFY_RAW_REGEXP = Regexp.new('\\s+').freeze
|
||||
SLUGIFY_DEFAULT_REGEXP = Regexp.new("[^\\p{M}\\p{L}\\p{Nd}]+").freeze
|
||||
SLUGIFY_PRETTY_REGEXP = Regexp.new("[^\\p{M}\\p{L}\\p{Nd}._~!$&'()+,;=@]+").freeze
|
||||
SLUGIFY_ASCII_REGEXP = Regexp.new("[^[A-Za-z0-9]]+").freeze
|
||||
|
||||
# Takes a slug and turns it into a simple title.
|
||||
def titleize_slug(slug)
|
||||
slug.split("-").map!(&:capitalize).join(" ")
|
||||
end
|
||||
|
||||
# Non-destructive version of deep_merge_hashes! See that method.
|
||||
#
|
||||
# Returns the merged hashes.
|
||||
def deep_merge_hashes(master_hash, other_hash)
|
||||
deep_merge_hashes!(master_hash.dup, other_hash)
|
||||
end
|
||||
|
||||
# Merges a master hash with another hash, recursively.
|
||||
#
|
||||
# master_hash - the "parent" hash whose values will be overridden
|
||||
# other_hash - the other hash whose values will be persisted after the merge
|
||||
#
|
||||
# This code was lovingly stolen from some random gem:
|
||||
# http://gemjack.com/gems/tartan-0.1.1/classes/Hash.html
|
||||
#
|
||||
# Thanks to whoever made it.
|
||||
def deep_merge_hashes!(target, overwrite)
|
||||
merge_values(target, overwrite)
|
||||
merge_default_proc(target, overwrite)
|
||||
duplicate_frozen_values(target)
|
||||
|
||||
target
|
||||
end
|
||||
|
||||
def mergable?(value)
|
||||
value.is_a?(Hash) || value.is_a?(Drops::Drop)
|
||||
end
|
||||
|
||||
def duplicable?(obj)
|
||||
case obj
|
||||
when nil, false, true, Symbol, Numeric
|
||||
false
|
||||
else
|
||||
true
|
||||
end
|
||||
end
|
||||
|
||||
# Read array from the supplied hash favouring the singular key
|
||||
# and then the plural key, and handling any nil entries.
|
||||
#
|
||||
# hash - the hash to read from
|
||||
# singular_key - the singular key
|
||||
# plural_key - the plural key
|
||||
#
|
||||
# Returns an array
|
||||
def pluralized_array_from_hash(hash, singular_key, plural_key)
|
||||
array = []
|
||||
value = value_from_singular_key(hash, singular_key)
|
||||
value ||= value_from_plural_key(hash, plural_key)
|
||||
|
||||
array << value
|
||||
array.flatten!
|
||||
array.compact!
|
||||
array
|
||||
end
|
||||
|
||||
def value_from_singular_key(hash, key)
|
||||
hash[key] if hash.key?(key) || (hash.default_proc && hash[key])
|
||||
end
|
||||
|
||||
def value_from_plural_key(hash, key)
|
||||
if hash.key?(key) || (hash.default_proc && hash[key])
|
||||
val = hash[key]
|
||||
case val
|
||||
when String
|
||||
val.split
|
||||
when Array
|
||||
val.compact
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def transform_keys(hash)
|
||||
result = {}
|
||||
hash.each_key do |key|
|
||||
result[yield(key)] = hash[key]
|
||||
end
|
||||
result
|
||||
end
|
||||
|
||||
# Apply #to_sym to all keys in the hash
|
||||
#
|
||||
# hash - the hash to which to apply this transformation
|
||||
#
|
||||
# Returns a new hash with symbolized keys
|
||||
def symbolize_hash_keys(hash)
|
||||
transform_keys(hash) { |key| key.to_sym rescue key }
|
||||
end
|
||||
|
||||
# Apply #to_s to all keys in the Hash
|
||||
#
|
||||
# hash - the hash to which to apply this transformation
|
||||
#
|
||||
# Returns a new hash with stringified keys
|
||||
def stringify_hash_keys(hash)
|
||||
transform_keys(hash) { |key| key.to_s rescue key }
|
||||
end
|
||||
|
||||
# Parse a date/time and throw an error if invalid
|
||||
#
|
||||
# input - the date/time to parse
|
||||
# msg - (optional) the error message to show the user
|
||||
#
|
||||
# Returns the parsed date if successful, throws a FatalException
|
||||
# if not
|
||||
def parse_date(input, msg = "Input could not be parsed.")
|
||||
Time.parse(input).localtime
|
||||
rescue ArgumentError
|
||||
raise Errors::InvalidDateError, "Invalid date '#{input}': #{msg}"
|
||||
end
|
||||
|
||||
# Determines whether a given file has
|
||||
#
|
||||
# Returns true if the YAML front matter is present.
|
||||
# rubocop: disable Naming/PredicateName
|
||||
def has_yaml_header?(file)
|
||||
File.open(file, "rb", &:readline).match? %r!\A---\s*\r?\n!
|
||||
rescue EOFError
|
||||
false
|
||||
end
|
||||
|
||||
# Determine whether the given content string contains Liquid Tags or Vaiables
|
||||
#
|
||||
# Returns true is the string contains sequences of `{%` or `{{`
|
||||
def has_liquid_construct?(content)
|
||||
return false if content.nil? || content.empty?
|
||||
|
||||
content.include?("{%") || content.include?("{{")
|
||||
end
|
||||
# rubocop: enable Naming/PredicateName
|
||||
|
||||
# Slugify a filename or title.
|
||||
#
|
||||
# string - the filename or title to slugify
|
||||
# mode - how string is slugified
|
||||
# cased - whether to replace all uppercase letters with their
|
||||
# lowercase counterparts
|
||||
#
|
||||
# When mode is "none", return the given string.
|
||||
#
|
||||
# When mode is "raw", return the given string,
|
||||
# with every sequence of spaces characters replaced with a hyphen.
|
||||
#
|
||||
# When mode is "default" or nil, non-alphabetic characters are
|
||||
# replaced with a hyphen too.
|
||||
#
|
||||
# When mode is "pretty", some non-alphabetic characters (._~!$&'()+,;=@)
|
||||
# are not replaced with hyphen.
|
||||
#
|
||||
# When mode is "ascii", some everything else except ASCII characters
|
||||
# a-z (lowercase), A-Z (uppercase) and 0-9 (numbers) are not replaced with hyphen.
|
||||
#
|
||||
# When mode is "latin", the input string is first preprocessed so that
|
||||
# any letters with accents are replaced with the plain letter. Afterwards,
|
||||
# it follows the "default" mode of operation.
|
||||
#
|
||||
# If cased is true, all uppercase letters in the result string are
|
||||
# replaced with their lowercase counterparts.
|
||||
#
|
||||
# Examples:
|
||||
# slugify("The _config.yml file")
|
||||
# # => "the-config-yml-file"
|
||||
#
|
||||
# slugify("The _config.yml file", "pretty")
|
||||
# # => "the-_config.yml-file"
|
||||
#
|
||||
# slugify("The _config.yml file", "pretty", true)
|
||||
# # => "The-_config.yml file"
|
||||
#
|
||||
# slugify("The _config.yml file", "ascii")
|
||||
# # => "the-config-yml-file"
|
||||
#
|
||||
# slugify("The _config.yml file", "latin")
|
||||
# # => "the-config-yml-file"
|
||||
#
|
||||
# Returns the slugified string.
|
||||
def slugify(string, mode: nil, cased: false)
|
||||
mode ||= "default"
|
||||
return nil if string.nil?
|
||||
|
||||
unless SLUGIFY_MODES.include?(mode)
|
||||
return cased ? string : string.downcase
|
||||
end
|
||||
|
||||
# Drop accent marks from latin characters. Everything else turns to ?
|
||||
if mode == "latin"
|
||||
I18n.config.available_locales = :en if I18n.config.available_locales.empty?
|
||||
string = I18n.transliterate(string)
|
||||
end
|
||||
|
||||
slug = replace_character_sequence_with_hyphen(string, :mode => mode)
|
||||
|
||||
# Remove leading/trailing hyphen
|
||||
slug.gsub!(%r!^-|-$!i, "")
|
||||
|
||||
slug.downcase! unless cased
|
||||
Jekyll.logger.warn("Warning:", "Empty `slug` generated for '#{string}'.") if slug.empty?
|
||||
slug
|
||||
end
|
||||
|
||||
# Add an appropriate suffix to template so that it matches the specified
|
||||
# permalink style.
|
||||
#
|
||||
# template - permalink template without trailing slash or file extension
|
||||
# permalink_style - permalink style, either built-in or custom
|
||||
#
|
||||
# The returned permalink template will use the same ending style as
|
||||
# specified in permalink_style. For example, if permalink_style contains a
|
||||
# trailing slash (or is :pretty, which indirectly has a trailing slash),
|
||||
# then so will the returned template. If permalink_style has a trailing
|
||||
# ":output_ext" (or is :none, :date, or :ordinal) then so will the returned
|
||||
# template. Otherwise, template will be returned without modification.
|
||||
#
|
||||
# Examples:
|
||||
# add_permalink_suffix("/:basename", :pretty)
|
||||
# # => "/:basename/"
|
||||
#
|
||||
# add_permalink_suffix("/:basename", :date)
|
||||
# # => "/:basename:output_ext"
|
||||
#
|
||||
# add_permalink_suffix("/:basename", "/:year/:month/:title/")
|
||||
# # => "/:basename/"
|
||||
#
|
||||
# add_permalink_suffix("/:basename", "/:year/:month/:title")
|
||||
# # => "/:basename"
|
||||
#
|
||||
# Returns the updated permalink template
|
||||
def add_permalink_suffix(template, permalink_style)
|
||||
template = template.dup
|
||||
|
||||
case permalink_style
|
||||
when :pretty
|
||||
template << "/"
|
||||
when :date, :ordinal, :none
|
||||
template << ":output_ext"
|
||||
else
|
||||
template << "/" if permalink_style.to_s.end_with?("/")
|
||||
template << ":output_ext" if permalink_style.to_s.end_with?(":output_ext")
|
||||
end
|
||||
|
||||
template
|
||||
end
|
||||
|
||||
# Work the same way as Dir.glob but seperating the input into two parts
|
||||
# ('dir' + '/' + 'pattern') to make sure the first part('dir') does not act
|
||||
# as a pattern.
|
||||
#
|
||||
# For example, Dir.glob("path[/*") always returns an empty array,
|
||||
# because the method fails to find the closing pattern to '[' which is ']'
|
||||
#
|
||||
# Examples:
|
||||
# safe_glob("path[", "*")
|
||||
# # => ["path[/file1", "path[/file2"]
|
||||
#
|
||||
# safe_glob("path", "*", File::FNM_DOTMATCH)
|
||||
# # => ["path/.", "path/..", "path/file1"]
|
||||
#
|
||||
# safe_glob("path", ["**", "*"])
|
||||
# # => ["path[/file1", "path[/folder/file2"]
|
||||
#
|
||||
# dir - the dir where glob will be executed under
|
||||
# (the dir will be included to each result)
|
||||
# patterns - the patterns (or the pattern) which will be applied under the dir
|
||||
# flags - the flags which will be applied to the pattern
|
||||
#
|
||||
# Returns matched pathes
|
||||
def safe_glob(dir, patterns, flags = 0)
|
||||
return [] unless Dir.exist?(dir)
|
||||
|
||||
pattern = File.join(Array(patterns))
|
||||
return [dir] if pattern.empty?
|
||||
|
||||
Dir.chdir(dir) do
|
||||
Dir.glob(pattern, flags).map { |f| File.join(dir, f) }
|
||||
end
|
||||
end
|
||||
|
||||
# Returns merged option hash for File.read of self.site (if exists)
|
||||
# and a given param
|
||||
def merged_file_read_opts(site, opts)
|
||||
merged = (site ? site.file_read_opts : {}).merge(opts)
|
||||
if merged[:encoding] && !merged[:encoding].start_with?("bom|")
|
||||
merged[:encoding] = "bom|#{merged[:encoding]}"
|
||||
end
|
||||
if merged["encoding"] && !merged["encoding"].start_with?("bom|")
|
||||
merged["encoding"] = "bom|#{merged["encoding"]}"
|
||||
end
|
||||
merged
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def merge_values(target, overwrite)
|
||||
target.merge!(overwrite) do |_key, old_val, new_val|
|
||||
if new_val.nil?
|
||||
old_val
|
||||
elsif mergable?(old_val) && mergable?(new_val)
|
||||
deep_merge_hashes(old_val, new_val)
|
||||
else
|
||||
new_val
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def merge_default_proc(target, overwrite)
|
||||
if target.is_a?(Hash) && overwrite.is_a?(Hash) && target.default_proc.nil?
|
||||
target.default_proc = overwrite.default_proc
|
||||
end
|
||||
end
|
||||
|
||||
def duplicate_frozen_values(target)
|
||||
target.each do |key, val|
|
||||
target[key] = val.dup if val.frozen? && duplicable?(val)
|
||||
end
|
||||
end
|
||||
|
||||
# Replace each character sequence with a hyphen.
|
||||
#
|
||||
# See Utils#slugify for a description of the character sequence specified
|
||||
# by each mode.
|
||||
def replace_character_sequence_with_hyphen(string, mode: "default")
|
||||
replaceable_char =
|
||||
case mode
|
||||
when "raw"
|
||||
SLUGIFY_RAW_REGEXP
|
||||
when "pretty"
|
||||
# "._~!$&'()+,;=@" is human readable (not URI-escaped) in URL
|
||||
# and is allowed in both extN and NTFS.
|
||||
SLUGIFY_PRETTY_REGEXP
|
||||
when "ascii"
|
||||
# For web servers not being able to handle Unicode, the safe
|
||||
# method is to ditch anything else but latin letters and numeric
|
||||
# digits.
|
||||
SLUGIFY_ASCII_REGEXP
|
||||
else
|
||||
SLUGIFY_DEFAULT_REGEXP
|
||||
end
|
||||
|
||||
# Strip according to the mode
|
||||
string.gsub(replaceable_char, "-")
|
||||
end
|
||||
end
|
||||
end
|
||||
57
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/utils/ansi.rb
vendored
Normal file
57
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/utils/ansi.rb
vendored
Normal file
@@ -0,0 +1,57 @@
|
||||
# Frozen-string-literal: true
|
||||
|
||||
module Jekyll
|
||||
module Utils
|
||||
module Ansi
|
||||
extend self
|
||||
|
||||
ESCAPE = format("%c", 27)
|
||||
MATCH = %r!#{ESCAPE}\[(?:\d+)(?:;\d+)*(j|k|m|s|u|A|B|G)|\e\(B\e\[m!ix.freeze
|
||||
COLORS = {
|
||||
:red => 31,
|
||||
:green => 32,
|
||||
:black => 30,
|
||||
:magenta => 35,
|
||||
:yellow => 33,
|
||||
:white => 37,
|
||||
:blue => 34,
|
||||
:cyan => 36,
|
||||
}.freeze
|
||||
|
||||
# Strip ANSI from the current string. It also strips cursor stuff,
|
||||
# well some of it, and it also strips some other stuff that a lot of
|
||||
# the other ANSI strippers don't.
|
||||
|
||||
def strip(str)
|
||||
str.gsub MATCH, ""
|
||||
end
|
||||
|
||||
#
|
||||
|
||||
def has?(str)
|
||||
!!(str =~ MATCH)
|
||||
end
|
||||
|
||||
# Reset the color back to the default color so that you do not leak any
|
||||
# colors when you move onto the next line. This is probably normally
|
||||
# used as part of a wrapper so that we don't leak colors.
|
||||
|
||||
def reset(str = "")
|
||||
@ansi_reset ||= format("%c[0m", 27)
|
||||
"#{@ansi_reset}#{str}"
|
||||
end
|
||||
|
||||
# SEE: `self::COLORS` for a list of methods. They are mostly
|
||||
# standard base colors supported by pretty much any xterm-color, we do
|
||||
# not need more than the base colors so we do not include them.
|
||||
# Actually... if I'm honest we don't even need most of the
|
||||
# base colors.
|
||||
|
||||
COLORS.each do |color, num|
|
||||
define_method color do |str|
|
||||
"#{format("%c", 27)}[#{num}m#{str}#{reset}"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
26
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/utils/exec.rb
vendored
Normal file
26
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/utils/exec.rb
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "open3"
|
||||
|
||||
module Jekyll
|
||||
module Utils
|
||||
module Exec
|
||||
extend self
|
||||
|
||||
# Runs a program in a sub-shell.
|
||||
#
|
||||
# *args - a list of strings containing the program name and arguments
|
||||
#
|
||||
# Returns a Process::Status and a String of output in an array in
|
||||
# that order.
|
||||
def run(*args)
|
||||
stdin, stdout, stderr, process = Open3.popen3(*args)
|
||||
out = stdout.read.strip
|
||||
err = stderr.read.strip
|
||||
|
||||
[stdin, stdout, stderr].each(&:close)
|
||||
[process.value, out + err]
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
37
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/utils/internet.rb
vendored
Normal file
37
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/utils/internet.rb
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Jekyll
|
||||
module Utils
|
||||
module Internet
|
||||
# Public: Determine whether the present device has a connection to
|
||||
# the Internet. This allows plugin writers which require the outside
|
||||
# world to have a neat fallback mechanism for offline building.
|
||||
#
|
||||
# Example:
|
||||
# if Internet.connected?
|
||||
# Typhoeus.get("https://pages.github.com/versions.json")
|
||||
# else
|
||||
# Jekyll.logger.warn "Warning:", "Version check has been disabled."
|
||||
# Jekyll.logger.warn "", "Connect to the Internet to enable it."
|
||||
# nil
|
||||
# end
|
||||
#
|
||||
# Returns true if a DNS call can successfully be made, or false if not.
|
||||
|
||||
module_function
|
||||
|
||||
def connected?
|
||||
!dns("example.com").nil?
|
||||
end
|
||||
|
||||
def dns(domain)
|
||||
require "resolv"
|
||||
Resolv::DNS.open do |resolver|
|
||||
resolver.getaddress(domain)
|
||||
end
|
||||
rescue Resolv::ResolvError, Resolv::ResolvTimeout
|
||||
nil
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
67
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/utils/platforms.rb
vendored
Normal file
67
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/utils/platforms.rb
vendored
Normal file
@@ -0,0 +1,67 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Jekyll
|
||||
module Utils
|
||||
module Platforms
|
||||
extend self
|
||||
|
||||
def jruby?
|
||||
RUBY_ENGINE == "jruby"
|
||||
end
|
||||
|
||||
def mri?
|
||||
RUBY_ENGINE == "ruby"
|
||||
end
|
||||
|
||||
def windows?
|
||||
vanilla_windows? || bash_on_windows?
|
||||
end
|
||||
|
||||
# Not a Windows Subsystem for Linux (WSL)
|
||||
def vanilla_windows?
|
||||
rbconfig_host.match?(%r!mswin|mingw|cygwin!) && proc_version.empty?
|
||||
end
|
||||
alias_method :really_windows?, :vanilla_windows?
|
||||
|
||||
# Determine if Windows Subsystem for Linux (WSL)
|
||||
def bash_on_windows?
|
||||
linux_os? && microsoft_proc_version?
|
||||
end
|
||||
|
||||
def linux?
|
||||
linux_os? && !microsoft_proc_version?
|
||||
end
|
||||
|
||||
def osx?
|
||||
rbconfig_host.match?(%r!darwin|mac os!)
|
||||
end
|
||||
|
||||
def unix?
|
||||
rbconfig_host.match?(%r!solaris|bsd!)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def proc_version
|
||||
@proc_version ||= \
|
||||
begin
|
||||
File.read("/proc/version").downcase
|
||||
rescue Errno::ENOENT, Errno::EACCES
|
||||
""
|
||||
end
|
||||
end
|
||||
|
||||
def rbconfig_host
|
||||
@rbconfig_host ||= RbConfig::CONFIG["host_os"].downcase
|
||||
end
|
||||
|
||||
def linux_os?
|
||||
rbconfig_host.include?("linux")
|
||||
end
|
||||
|
||||
def microsoft_proc_version?
|
||||
proc_version.include?("microsoft")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
31
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/utils/thread_event.rb
vendored
Normal file
31
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/utils/thread_event.rb
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Jekyll
|
||||
module Utils
|
||||
# Based on the pattern and code from
|
||||
# https://emptysqua.re/blog/an-event-synchronization-primitive-for-ruby/
|
||||
class ThreadEvent
|
||||
attr_reader :flag
|
||||
|
||||
def initialize
|
||||
@lock = Mutex.new
|
||||
@cond = ConditionVariable.new
|
||||
@flag = false
|
||||
end
|
||||
|
||||
def set
|
||||
@lock.synchronize do
|
||||
yield if block_given?
|
||||
@flag = true
|
||||
@cond.broadcast
|
||||
end
|
||||
end
|
||||
|
||||
def wait
|
||||
@lock.synchronize do
|
||||
@cond.wait(@lock) unless @flag
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
75
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/utils/win_tz.rb
vendored
Normal file
75
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/utils/win_tz.rb
vendored
Normal file
@@ -0,0 +1,75 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Jekyll
|
||||
module Utils
|
||||
module WinTZ
|
||||
extend self
|
||||
|
||||
# Public: Calculate the Timezone for Windows when the config file has a defined
|
||||
# 'timezone' key.
|
||||
#
|
||||
# timezone - the IANA Time Zone specified in "_config.yml"
|
||||
#
|
||||
# Returns a string that ultimately re-defines ENV["TZ"] in Windows
|
||||
def calculate(timezone)
|
||||
External.require_with_graceful_fail("tzinfo") unless defined?(TZInfo)
|
||||
tz = TZInfo::Timezone.get(timezone)
|
||||
difference = Time.now.to_i - tz.now.to_i
|
||||
#
|
||||
# POSIX style definition reverses the offset sign.
|
||||
# e.g. Eastern Standard Time (EST) that is 5Hrs. to the 'west' of Prime Meridian
|
||||
# is denoted as:
|
||||
# EST+5 (or) EST+05:00
|
||||
# Reference: http://www.gnu.org/software/libc/manual/html_node/TZ-Variable.html
|
||||
sign = difference.negative? ? "-" : "+"
|
||||
offset = sign == "-" ? "+" : "-" unless difference.zero?
|
||||
#
|
||||
# convert the difference (in seconds) to hours, as a rational number, and perform
|
||||
# a modulo operation on it.
|
||||
modulo = modulo_of(rational_hour(difference))
|
||||
#
|
||||
# Format the hour as a two-digit number.
|
||||
# Establish the minutes based on modulo expression.
|
||||
hh = format("%<hour>02d", :hour => absolute_hour(difference).ceil)
|
||||
mm = modulo.zero? ? "00" : "30"
|
||||
|
||||
Jekyll.logger.debug "Timezone:", "#{timezone} #{offset}#{hh}:#{mm}"
|
||||
#
|
||||
# Note: The 3-letter-word below doesn't have a particular significance.
|
||||
"WTZ#{sign}#{hh}:#{mm}"
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# Private: Convert given seconds to an hour as a rational number.
|
||||
#
|
||||
# seconds - supplied as an integer, it is converted to a rational number.
|
||||
# 3600 - no. of seconds in an hour.
|
||||
#
|
||||
# Returns a rational number.
|
||||
def rational_hour(seconds)
|
||||
seconds.to_r / 3600
|
||||
end
|
||||
|
||||
# Private: Convert given seconds to an hour as an absolute number.
|
||||
#
|
||||
# seconds - supplied as an integer, it is converted to its absolute.
|
||||
# 3600 - no. of seconds in an hour.
|
||||
#
|
||||
# Returns an integer.
|
||||
def absolute_hour(seconds)
|
||||
seconds.abs / 3600
|
||||
end
|
||||
|
||||
# Private: Perform a modulo operation on a given fraction.
|
||||
#
|
||||
# fraction - supplied as a rational number, its numerator is divided
|
||||
# by its denominator and the remainder returned.
|
||||
#
|
||||
# Returns an integer.
|
||||
def modulo_of(fraction)
|
||||
fraction.numerator % fraction.denominator
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
5
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/version.rb
vendored
Normal file
5
vendor/bundle/ruby/2.6.0/gems/jekyll-4.2.0/lib/jekyll/version.rb
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Jekyll
|
||||
VERSION = "4.2.0"
|
||||
end
|
||||
Reference in New Issue
Block a user