distorted-jekyll 0.5.6 → 0.5.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/LICENSE +661 -0
- data/README.md +6 -10
- data/lib/distorted-jekyll.rb +79 -0
- data/lib/distorted-jekyll/13th-style.rb +58 -0
- data/lib/distorted-jekyll/_config_default.yml +79 -0
- data/lib/distorted-jekyll/blocks.rb +16 -0
- data/lib/distorted-jekyll/error_code.rb +24 -0
- data/lib/distorted-jekyll/floor.rb +148 -0
- data/lib/distorted-jekyll/injection_of_love.rb +305 -0
- data/lib/distorted-jekyll/invoker.rb +400 -0
- data/lib/distorted-jekyll/molecule/abstract.rb +238 -0
- data/lib/distorted-jekyll/molecule/font.rb +29 -0
- data/lib/distorted-jekyll/molecule/image.rb +105 -0
- data/lib/distorted-jekyll/molecule/last-resort.rb +54 -0
- data/lib/distorted-jekyll/molecule/pdf.rb +88 -0
- data/lib/distorted-jekyll/molecule/svg.rb +59 -0
- data/lib/distorted-jekyll/molecule/text.rb +74 -0
- data/lib/distorted-jekyll/molecule/video.rb +43 -0
- data/lib/distorted-jekyll/monkey_business/jekyll/cleaner.rb +54 -0
- data/lib/distorted-jekyll/static/font.rb +42 -0
- data/lib/distorted-jekyll/static/image.rb +55 -0
- data/lib/distorted-jekyll/static/lastresort.rb +28 -0
- data/lib/distorted-jekyll/static/pdf.rb +53 -0
- data/lib/distorted-jekyll/static/state.rb +141 -0
- data/lib/distorted-jekyll/static/svg.rb +52 -0
- data/lib/distorted-jekyll/static/text.rb +57 -0
- data/lib/distorted-jekyll/static/video.rb +90 -0
- data/lib/distorted-jekyll/template/13th-style.css +78 -0
- data/lib/distorted-jekyll/template/error_code.liquid +3 -0
- data/lib/distorted-jekyll/template/font.liquid +32 -0
- data/lib/distorted-jekyll/template/image.liquid +32 -0
- data/lib/distorted-jekyll/template/lastresort.liquid +20 -0
- data/lib/distorted-jekyll/template/pdf.liquid +14 -0
- data/lib/distorted-jekyll/template/svg.liquid +32 -0
- data/lib/distorted-jekyll/template/text.liquid +32 -0
- data/lib/distorted-jekyll/template/video.liquid +11 -0
- metadata +41 -6
@@ -0,0 +1,59 @@
|
|
1
|
+
require 'set'
|
2
|
+
|
3
|
+
require 'distorted/svg'
|
4
|
+
require 'distorted-jekyll/static/svg'
|
5
|
+
|
6
|
+
module Jekyll
|
7
|
+
module DistorteD
|
8
|
+
module Molecule
|
9
|
+
module SVG
|
10
|
+
|
11
|
+
# Reference these instead of reassigning them. Consistency is mandatory.
|
12
|
+
MEDIA_TYPE = Cooltrainer::DistorteD::SVG::MEDIA_TYPE
|
13
|
+
SUB_TYPE = Cooltrainer::DistorteD::SVG::SUB_TYPE
|
14
|
+
MIME_TYPES = Cooltrainer::DistorteD::SVG::MIME_TYPES
|
15
|
+
|
16
|
+
ATTRS = Cooltrainer::DistorteD::SVG::ATTRS
|
17
|
+
ATTRS_DEFAULT = Cooltrainer::DistorteD::SVG::ATTRS_DEFAULT
|
18
|
+
ATTRS_VALUES = Cooltrainer::DistorteD::SVG::ATTRS_VALUES
|
19
|
+
|
20
|
+
|
21
|
+
def render_to_output_buffer(context, output)
|
22
|
+
super
|
23
|
+
begin
|
24
|
+
# Liquid doesn't seem able to reference symbolic keys,
|
25
|
+
# so convert everything to string for template.
|
26
|
+
# Not stripping :full tags like Image because all of our
|
27
|
+
# SVG variations will be full-res for now.
|
28
|
+
filez = files.map{ |f|
|
29
|
+
f.transform_values(&:to_s).transform_keys(&:to_s)
|
30
|
+
}
|
31
|
+
output << parse_template.render({
|
32
|
+
'name' => @name,
|
33
|
+
'path' => @dd_dest,
|
34
|
+
'alt' => attr_value(:alt),
|
35
|
+
'title' => attr_value(:title),
|
36
|
+
'href' => attr_value(:href),
|
37
|
+
'caption' => attr_value(:caption),
|
38
|
+
'loading' => attr_value(:loading),
|
39
|
+
'sources' => filez,
|
40
|
+
'fallback_img' => @name,
|
41
|
+
})
|
42
|
+
rescue Liquid::SyntaxError => l
|
43
|
+
unless Jekyll.env == 'production'.freeze
|
44
|
+
output << parse_template(name: 'error_code'.freeze).render({
|
45
|
+
'message' => l.message,
|
46
|
+
})
|
47
|
+
end
|
48
|
+
end
|
49
|
+
output
|
50
|
+
end
|
51
|
+
|
52
|
+
def static_file(*args)
|
53
|
+
Jekyll::DistorteD::Static::SVG.new(*args)
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
require 'set'
|
2
|
+
|
3
|
+
require 'distorted/text'
|
4
|
+
require 'distorted-jekyll/static/text'
|
5
|
+
|
6
|
+
module Jekyll
|
7
|
+
module DistorteD
|
8
|
+
module Molecule
|
9
|
+
module Text
|
10
|
+
|
11
|
+
DRIVER = Cooltrainer::DistorteD::Text
|
12
|
+
|
13
|
+
MEDIA_TYPE = DRIVER::MEDIA_TYPE
|
14
|
+
MIME_TYPES = DRIVER::MIME_TYPES
|
15
|
+
|
16
|
+
ATTRS = DRIVER::ATTRS
|
17
|
+
ATTRS_DEFAULT = DRIVER::ATTRS_DEFAULT
|
18
|
+
ATTRS_VALUES = DRIVER::ATTRS_VALUES
|
19
|
+
|
20
|
+
|
21
|
+
def render_to_output_buffer(context, output)
|
22
|
+
super
|
23
|
+
begin
|
24
|
+
filez = files.keep_if{ |f|
|
25
|
+
# Strip out all non-displayable media-types, e.g. the actual text/whatever.
|
26
|
+
f.key?(:type) && f&.dig(:type)&.media_type == 'image'.freeze
|
27
|
+
}.keep_if{ |f|
|
28
|
+
# Strip out full-size images (will have `nil`) — only display thumbnail vers
|
29
|
+
f.key?(:width) or f.key?(:height)
|
30
|
+
}.map{ |f|
|
31
|
+
# Stringify to make Liquid happy
|
32
|
+
f.transform_values(&:to_s).transform_keys(&:to_s)
|
33
|
+
}
|
34
|
+
output << parse_template.render({
|
35
|
+
'name' => @name,
|
36
|
+
'path' => @dd_dest,
|
37
|
+
'alt' => attr_value(:alt),
|
38
|
+
'title' => attr_value(:title),
|
39
|
+
'sources' => filez,
|
40
|
+
'fallback_img' => fallback_img,
|
41
|
+
})
|
42
|
+
rescue Liquid::SyntaxError => l
|
43
|
+
unless Jekyll.env == 'production'.freeze
|
44
|
+
output << parse_template(name: 'error_code'.freeze).render({
|
45
|
+
'message' => l.message,
|
46
|
+
})
|
47
|
+
end
|
48
|
+
end
|
49
|
+
output
|
50
|
+
end
|
51
|
+
|
52
|
+
# Return the filename of the most-compatible output image
|
53
|
+
# for use as the fallback <img> tag inside our <picture>.
|
54
|
+
def fallback_img
|
55
|
+
best_ver = nil
|
56
|
+
files.keep_if{|f| f.key?(:type) && f&.dig(:type)&.media_type == 'image'.freeze}.each{ |f|
|
57
|
+
# PNG > WebP
|
58
|
+
if f&.dig(:type)&.sub_type == 'png'.freeze || best_ver.nil?
|
59
|
+
best_ver = f
|
60
|
+
end
|
61
|
+
}
|
62
|
+
# Return the filename of the biggest matched variation,
|
63
|
+
# otherwise use the original filename.
|
64
|
+
best_ver&.dig(:name) || @name
|
65
|
+
end
|
66
|
+
|
67
|
+
def static_file(*args)
|
68
|
+
Jekyll::DistorteD::Static::Text.new(*args)
|
69
|
+
end
|
70
|
+
|
71
|
+
end # Text
|
72
|
+
end # Molecule
|
73
|
+
end # DistorteD
|
74
|
+
end # Jekyll
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'distorted/video'
|
2
|
+
require 'distorted-jekyll/static/video'
|
3
|
+
|
4
|
+
module Jekyll
|
5
|
+
module DistorteD
|
6
|
+
module Molecule
|
7
|
+
module Video
|
8
|
+
|
9
|
+
# Reference these instead of reassigning them. Consistency is mandatory.
|
10
|
+
MEDIA_TYPE = Cooltrainer::DistorteD::Video::MEDIA_TYPE
|
11
|
+
MIME_TYPES = Cooltrainer::DistorteD::Video::MIME_TYPES
|
12
|
+
|
13
|
+
ATTRS = Cooltrainer::DistorteD::Video::ATTRS
|
14
|
+
ATTRS_DEFAULT = Cooltrainer::DistorteD::Video::ATTRS_DEFAULT
|
15
|
+
ATTRS_VALUES = Cooltrainer::DistorteD::Video::ATTRS_VALUES
|
16
|
+
|
17
|
+
def render_to_output_buffer(context, output)
|
18
|
+
super
|
19
|
+
begin
|
20
|
+
output << parse_template.render({
|
21
|
+
'name' => @name,
|
22
|
+
'basename' => File.basename(@name, '.*'),
|
23
|
+
'path' => @url,
|
24
|
+
'caption' => attr_value(:caption),
|
25
|
+
})
|
26
|
+
rescue Liquid::SyntaxError => l
|
27
|
+
unless Jekyll.env == 'production'.freeze
|
28
|
+
output << parse_template(name: 'error_code'.freeze).render({
|
29
|
+
'message' => l.message,
|
30
|
+
})
|
31
|
+
end
|
32
|
+
end
|
33
|
+
output
|
34
|
+
end
|
35
|
+
|
36
|
+
def static_file(*args)
|
37
|
+
Jekyll::DistorteD::Static::Video.new(*args)
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
require 'set'
|
2
|
+
|
3
|
+
module Jekyll
|
4
|
+
# Handles the cleanup of a site's destination before it is built or re-built.
|
5
|
+
class Cleaner
|
6
|
+
|
7
|
+
# Private: The list of files to be created when site is built.
|
8
|
+
#
|
9
|
+
# Returns a Set with the file paths
|
10
|
+
#
|
11
|
+
# Monkey-patch this to look for DD's unique `destinations` which is similar
|
12
|
+
# to the original `destination` method except it returns a Set of destination
|
13
|
+
# paths instead of a single destination path.
|
14
|
+
# Do the patch with `define_method` instead of just `def` because the block's
|
15
|
+
# closure of the local scope lets it carry a binding to the original overriden
|
16
|
+
# method which I use to bail out iff the monkey-patch fails.
|
17
|
+
# This is an attempt to avoid breaking future Jekyll versions as much as
|
18
|
+
# possible, since any Exception in the monkey-patched code will just cause
|
19
|
+
# the original Jekyll implementation to be called instead.
|
20
|
+
# The new worst case scenario is slow site builds due to media variation generation!
|
21
|
+
#
|
22
|
+
# If a StaticFile responds to `destinations` then use it and merge the result.
|
23
|
+
# I'm defining my own separate method for multi-destinations for now,
|
24
|
+
# but I also considered just overriding `destination` to return the Set and
|
25
|
+
# then doing this as a one-liner that handles either case (single or
|
26
|
+
# multiple destinations) with `files.merge(Set[*(item.destination(site.dest))])`.
|
27
|
+
# This is the safer choice though since we avoid changing the outout type of the
|
28
|
+
# regular `:destination` method.
|
29
|
+
the_old_new_thing = instance_method(:new_files)
|
30
|
+
define_method(:new_files) do
|
31
|
+
begin
|
32
|
+
@new_files ||= Set.new.tap do |files|
|
33
|
+
site.each_site_file { |item|
|
34
|
+
if item.respond_to?(:destinations)
|
35
|
+
files.merge(item.destinations(site.dest))
|
36
|
+
elsif item.respond_to?(:destination)
|
37
|
+
files << item.destination(site.dest)
|
38
|
+
else
|
39
|
+
# Something unrelated has gone wrong for us to end up sending
|
40
|
+
# `destination` to something that doesn't respond to it.
|
41
|
+
# We should fall back to the original implementation of `new_files`
|
42
|
+
# in this case so the failure doesn't appear to be here.
|
43
|
+
the_old_new_thing.bind(self).()
|
44
|
+
end
|
45
|
+
}
|
46
|
+
end
|
47
|
+
rescue RuntimeError => e
|
48
|
+
Jekyll.logger.warn('DistorteD', "Monkey-patching Jekyll::Cleaner#new_files failed: #{e.message}")
|
49
|
+
Jekyll.logger.debug('DistorteD', "Monkey-patched Jekyll::Cleaner#new_files backtrace: #{e.backtrace}")
|
50
|
+
the_old_new_thing.bind(self).()
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end # Cleaner
|
54
|
+
end # Jekyll
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
require 'set'
|
3
|
+
|
4
|
+
require 'distorted/font'
|
5
|
+
require 'distorted-jekyll/static/text'
|
6
|
+
|
7
|
+
module Jekyll
|
8
|
+
module DistorteD
|
9
|
+
module Static
|
10
|
+
class Font < Text
|
11
|
+
|
12
|
+
DRIVER = Cooltrainer::DistorteD::Font
|
13
|
+
|
14
|
+
MEDIA_TYPE = DRIVER::MEDIA_TYPE
|
15
|
+
MIME_TYPES = DRIVER::MIME_TYPES
|
16
|
+
|
17
|
+
ATTRS = DRIVER::ATTRS
|
18
|
+
ATTRS_DEFAULT = DRIVER::ATTRS_DEFAULT
|
19
|
+
ATTRS_VALUES = DRIVER::ATTRS_VALUES
|
20
|
+
|
21
|
+
|
22
|
+
# dest: String realpath to `_site` directory
|
23
|
+
def write(dest)
|
24
|
+
orig_dest = destination(dest)
|
25
|
+
|
26
|
+
return false if !modified?
|
27
|
+
self.class.mtimes[path] = mtime
|
28
|
+
|
29
|
+
@distorted = DRIVER.new(
|
30
|
+
path,
|
31
|
+
demo: attr_value(:title),
|
32
|
+
)
|
33
|
+
FileUtils.cp(path, File.join(dd_dest(dest), @name))
|
34
|
+
|
35
|
+
super
|
36
|
+
|
37
|
+
end
|
38
|
+
|
39
|
+
end # Text
|
40
|
+
end # Static
|
41
|
+
end # DistorteD
|
42
|
+
end # Jekyll
|
@@ -0,0 +1,55 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
require 'set'
|
3
|
+
|
4
|
+
require 'distorted/image'
|
5
|
+
require 'distorted-jekyll/static/state'
|
6
|
+
|
7
|
+
module Jekyll
|
8
|
+
module DistorteD
|
9
|
+
module Static
|
10
|
+
class Image < Jekyll::DistorteD::Static::State
|
11
|
+
|
12
|
+
DRIVER = Cooltrainer::DistorteD::Image
|
13
|
+
|
14
|
+
MEDIA_TYPE = DRIVER::MEDIA_TYPE
|
15
|
+
MIME_TYPES = DRIVER::MIME_TYPES
|
16
|
+
|
17
|
+
ATTRS = DRIVER::ATTRS
|
18
|
+
ATTRS_DEFAULT = DRIVER::ATTRS_DEFAULT
|
19
|
+
ATTRS_VALUES = DRIVER::ATTRS_VALUES
|
20
|
+
|
21
|
+
|
22
|
+
# dest: string realpath to `_site_` directory
|
23
|
+
def write(dest)
|
24
|
+
return false if File.exist?(path) && !modified?
|
25
|
+
self.class.mtimes[path] = mtime
|
26
|
+
|
27
|
+
# Create any directories to the depth of the intended destination.
|
28
|
+
FileUtils.mkdir_p(dd_dest(dest))
|
29
|
+
|
30
|
+
unless defined? @distorted
|
31
|
+
@distorted = DRIVER.new(path)
|
32
|
+
end
|
33
|
+
|
34
|
+
Jekyll.logger.debug(@tag_name, "Rotating #{@name} if tagged.")
|
35
|
+
@distorted.rotate(angle: :auto)
|
36
|
+
|
37
|
+
# Save every desired variation of this image.
|
38
|
+
# This will be a Set of Hashes each describing the name, type,
|
39
|
+
# dimensions, attributes, etc of each output variation we want.
|
40
|
+
# Full-size outputs will have the special tag `:full`.
|
41
|
+
for variation in files
|
42
|
+
if DRIVER::MIME_TYPES.include?(variation&.dig(:type))
|
43
|
+
filename = File.join(dd_dest(dest), variation&.dig(:name) || @name)
|
44
|
+
Jekyll.logger.debug('DistorteD Writing:', filename)
|
45
|
+
@distorted.save(filename, width: variation&.dig(:width), crop: variation&.dig(:crop))
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
true
|
50
|
+
end
|
51
|
+
|
52
|
+
end # Image
|
53
|
+
end # Static
|
54
|
+
end # DistorteD
|
55
|
+
end # Jekyll
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
require 'set'
|
3
|
+
|
4
|
+
require 'distorted-jekyll/static/state'
|
5
|
+
|
6
|
+
module Jekyll
|
7
|
+
module DistorteD
|
8
|
+
module Static
|
9
|
+
class LastResort < Jekyll::DistorteD::Static::State
|
10
|
+
|
11
|
+
# dest: string realpath to `_site_` directory
|
12
|
+
def write(dest)
|
13
|
+
return false if File.exist?(path) && !modified?
|
14
|
+
self.class.mtimes[path] = mtime
|
15
|
+
|
16
|
+
# Create any directories to the depth of the intended destination.
|
17
|
+
FileUtils.mkdir_p(dd_dest(dest))
|
18
|
+
|
19
|
+
Jekyll.logger.debug(@tag_name, "Copying #{@name} to #{dd_dest(dest)}")
|
20
|
+
FileUtils.cp(path, File.join(dd_dest(dest), @name))
|
21
|
+
|
22
|
+
true
|
23
|
+
end
|
24
|
+
|
25
|
+
end # Image
|
26
|
+
end # Static
|
27
|
+
end # DistorteD
|
28
|
+
end # Jekyll
|
@@ -0,0 +1,53 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
require 'set'
|
3
|
+
|
4
|
+
require 'distorted/pdf'
|
5
|
+
require 'distorted-jekyll/static/pdf'
|
6
|
+
|
7
|
+
|
8
|
+
module Jekyll
|
9
|
+
module DistorteD
|
10
|
+
module Static
|
11
|
+
class PDF < Jekyll::DistorteD::Static::State
|
12
|
+
|
13
|
+
DRIVER = Cooltrainer::DistorteD::PDF
|
14
|
+
|
15
|
+
MEDIA_TYPE = DRIVER::MEDIA_TYPE
|
16
|
+
SUB_TYPE = DRIVER::SUB_TYPE
|
17
|
+
MIME_TYPES = DRIVER::MIME_TYPES
|
18
|
+
|
19
|
+
ATTRS = DRIVER::ATTRS
|
20
|
+
ATTRS_DEFAULT = DRIVER::ATTRS_DEFAULT
|
21
|
+
ATTRS_VALUES = DRIVER::ATTRS_VALUES
|
22
|
+
|
23
|
+
|
24
|
+
# dest: string realpath to `_site_` directory
|
25
|
+
def write(dest)
|
26
|
+
return false if File.exist?(path) && !modified?
|
27
|
+
self.class.mtimes[path] = mtime
|
28
|
+
|
29
|
+
# Create any directories to the depth of the intended destination.
|
30
|
+
FileUtils.mkdir_p(dd_dest(dest))
|
31
|
+
|
32
|
+
for variation in files
|
33
|
+
if DRIVER::MIME_TYPES.include?(variation[:type])
|
34
|
+
pdf_dest_path = File.join(dd_dest(dest), variation[:name])
|
35
|
+
|
36
|
+
if true # TODO: Make this configurable
|
37
|
+
Jekyll.logger.debug(@tag_name, "Optimizing #{@name} and copying to #{dd_dest(dest)}")
|
38
|
+
# TODO: Make optimizations/plugins configurable
|
39
|
+
DRIVER::optimize(path, pdf_dest_path)
|
40
|
+
else
|
41
|
+
Jekyll.logger.debug(@tag_name, "Copying #{@name} to #{dd_dest(dest)}")
|
42
|
+
FileUtils.cp(path, pdf_dest_path)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
true
|
48
|
+
end
|
49
|
+
|
50
|
+
end # PDF
|
51
|
+
end # Static
|
52
|
+
end # DistorteD
|
53
|
+
end # Jekyll
|
@@ -0,0 +1,141 @@
|
|
1
|
+
require 'set'
|
2
|
+
|
3
|
+
require 'distorted-jekyll/molecule/abstract'
|
4
|
+
|
5
|
+
|
6
|
+
module Jekyll
|
7
|
+
module DistorteD
|
8
|
+
module Static
|
9
|
+
class State < Jekyll::StaticFile
|
10
|
+
|
11
|
+
include Jekyll::DistorteD::Molecule::Abstract
|
12
|
+
|
13
|
+
def initialize(
|
14
|
+
site,
|
15
|
+
base,
|
16
|
+
dir,
|
17
|
+
name,
|
18
|
+
mime,
|
19
|
+
attrs,
|
20
|
+
dd_dest,
|
21
|
+
url,
|
22
|
+
collection: nil
|
23
|
+
)
|
24
|
+
# e.g. 'DistorteD::Static::Image' or 'DistorteD::Static::Video'
|
25
|
+
@tag_name = self.class.name.split('::').drop(1).join('::').to_sym.freeze
|
26
|
+
|
27
|
+
# String path to Jekyll site root
|
28
|
+
@base = base
|
29
|
+
|
30
|
+
# String container dir (under `base`) of original file
|
31
|
+
@dir = dir
|
32
|
+
|
33
|
+
# String filename of original file
|
34
|
+
@name = name
|
35
|
+
|
36
|
+
# Union Set of MIME::Types between the original media file
|
37
|
+
# and the plugged MediaMolecule.
|
38
|
+
@mime = mime
|
39
|
+
|
40
|
+
# Attributes provided to our Liquid tag
|
41
|
+
@attrs = attrs
|
42
|
+
|
43
|
+
# String path to media generation output dir
|
44
|
+
# under Site.dest (which is currently unknown)
|
45
|
+
@dd_dest = dd_dest
|
46
|
+
|
47
|
+
# String destination URL for the post/page on which the media appears.
|
48
|
+
@url = url
|
49
|
+
|
50
|
+
# Hello yes
|
51
|
+
Jekyll.logger.debug(@tag_name, "#{base}/#{dir}/#{name} -> #{url}})")
|
52
|
+
|
53
|
+
# Construct Jekyll::StaticFile with only the args it takes:
|
54
|
+
super(
|
55
|
+
site,
|
56
|
+
base,
|
57
|
+
dir,
|
58
|
+
name,
|
59
|
+
)
|
60
|
+
end
|
61
|
+
|
62
|
+
def basename
|
63
|
+
File.basename(@name, '.*')
|
64
|
+
end
|
65
|
+
|
66
|
+
def extname
|
67
|
+
File.extname(@name)
|
68
|
+
end
|
69
|
+
|
70
|
+
# Returns the to-be-written path of a single standard StaticFile.
|
71
|
+
# The value returned by this method is only the 'main' or 'original'
|
72
|
+
# (even if modified somehow) file and does not include the
|
73
|
+
# path/filenames of any variations.
|
74
|
+
# This method will be called by jekyll/lib/cleaner#new_files
|
75
|
+
# to generate the list of files that need to be build or rebuilt
|
76
|
+
# for a site. For this reason, this method shouldn't do any kind
|
77
|
+
# of checking the real filesystem, since e.g. its URL-based
|
78
|
+
# destdir might not exist yet if the Site.dest is completely blank.
|
79
|
+
def destination(dest)
|
80
|
+
File.join(dest, @dd_dest, @name)
|
81
|
+
end
|
82
|
+
|
83
|
+
# Return the absolute path to the top-level destination directory
|
84
|
+
# of the currently-working media. This will usually be the same path
|
85
|
+
# as the Jekyll post/page's generated HTML output.
|
86
|
+
def dd_dest(dest)
|
87
|
+
File.join(dest, @dd_dest)
|
88
|
+
end
|
89
|
+
|
90
|
+
# This method will be called by our monkey-patched Jekyll::Cleaner#new_files
|
91
|
+
# in place of the single-destination method usually used.
|
92
|
+
# This allows us to tell Jekyll about more than a single file
|
93
|
+
# that should be kept when regenerating the site.
|
94
|
+
# This makes DistorteD fast!
|
95
|
+
def destinations(dest)
|
96
|
+
# TODO: Make outputting the original file optional. Will need to change
|
97
|
+
# templates, `modified?`s, and `generate`s to do that.
|
98
|
+
filenames.map{|f| File.join(dd_dest(dest), f)} << destination(dest)
|
99
|
+
end
|
100
|
+
|
101
|
+
# HACK HACK HACK
|
102
|
+
# Jekyll does not pass this method a site.dest like it does write() and
|
103
|
+
# others, but I want to be able to short-circuit here if all the
|
104
|
+
# to-be-generated files already exist.
|
105
|
+
def modified?
|
106
|
+
# Assume modified for the sake of freshness :)
|
107
|
+
modified = true
|
108
|
+
|
109
|
+
site_dest = Jekyll::DistorteD::Floor::config(:destination).to_s
|
110
|
+
if Dir.exist?(site_dest)
|
111
|
+
|
112
|
+
dd_dest = dd_dest(site_dest)
|
113
|
+
if Dir.exist?(dd_dest)
|
114
|
+
|
115
|
+
# TODO: Make outputting the original file conditional.
|
116
|
+
# Doing that will require changing the default href handling
|
117
|
+
# in the template, Jekyll::DistorteD::Static::State.destinations,
|
118
|
+
# as well as Cooltrainer::DistorteD::Image.generate
|
119
|
+
wanted_files = Set[@name].merge(filenames)
|
120
|
+
extant_files = Dir.entries(dd_dest).to_set
|
121
|
+
|
122
|
+
# TODO: Make this smarter. It's not enough that all the generated
|
123
|
+
# filenames should exist. Try a few more ways to detect subtler
|
124
|
+
# "changes to the source file since generation of variations.
|
125
|
+
if wanted_files.subset?(extant_files)
|
126
|
+
Jekyll.logger.debug(@name, "All variations present: #{wanted_files}")
|
127
|
+
modified = false
|
128
|
+
else
|
129
|
+
Jekyll.logger.debug(@name, "Missing variations: #{wanted_files - extant_files}")
|
130
|
+
end
|
131
|
+
|
132
|
+
end # dd_dest.exists?
|
133
|
+
end # site_dest.exists?
|
134
|
+
Jekyll.logger.debug("#{@name} modified?", modified)
|
135
|
+
return modified
|
136
|
+
end
|
137
|
+
|
138
|
+
end # state
|
139
|
+
end # Static
|
140
|
+
end # DistorteD
|
141
|
+
end # Jekyll
|