distorted-jekyll 0.5.3 → 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- 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 +81 -0
- data/lib/distorted-jekyll/blocks.rb +16 -0
- data/lib/distorted-jekyll/floor.rb +266 -0
- data/lib/distorted-jekyll/invoker.rb +259 -0
- data/lib/distorted-jekyll/md_injection.rb +305 -0
- data/lib/distorted-jekyll/molecule/font.rb +62 -0
- data/lib/distorted-jekyll/molecule/image.rb +94 -0
- data/lib/distorted-jekyll/molecule/lastresort.rb +51 -0
- data/lib/distorted-jekyll/molecule/pdf.rb +79 -0
- data/lib/distorted-jekyll/molecule/svg.rb +47 -0
- data/lib/distorted-jekyll/molecule/text.rb +62 -0
- data/lib/distorted-jekyll/molecule/video.rb +85 -0
- data/lib/distorted-jekyll/monkey_business/jekyll/cleaner.rb +54 -0
- data/lib/distorted-jekyll/static_state.rb +201 -0
- data/lib/distorted-jekyll/template/13th-style.css +79 -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 +32 -34
@@ -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,201 @@
|
|
1
|
+
|
2
|
+
require 'fileutils'
|
3
|
+
require 'set'
|
4
|
+
|
5
|
+
require 'distorted/error_code'
|
6
|
+
|
7
|
+
|
8
|
+
module Jekyll; end
|
9
|
+
module Jekyll::DistorteD; end
|
10
|
+
|
11
|
+
# This module implements the methods our tag needs in order to
|
12
|
+
# pretend to be a Jekyll::StaticFile so we don't need to
|
13
|
+
# redundantly re-implement a Generator and Jekyll::Cleaner.
|
14
|
+
module Jekyll::DistorteD::StaticState
|
15
|
+
|
16
|
+
|
17
|
+
ATTRIBUTES = Set[:title]
|
18
|
+
|
19
|
+
|
20
|
+
# Returns the to-be-written path of a single standard StaticFile.
|
21
|
+
# The value returned by this method is only the 'main' or 'original'
|
22
|
+
# (even if modified somehow) file and does not include the
|
23
|
+
# path/filenames of any variations.
|
24
|
+
# This method will be called by jekyll/lib/cleaner#new_files
|
25
|
+
# to generate the list of files that need to be build or rebuilt
|
26
|
+
# for a site. For this reason, this method shouldn't do any kind
|
27
|
+
# of checking the real filesystem, since e.g. its URL-based
|
28
|
+
# destdir might not exist yet if the Site.dest is completely blank.
|
29
|
+
def destination(dest_root)
|
30
|
+
File.join(dest_root, @relative_dest, @name)
|
31
|
+
end
|
32
|
+
|
33
|
+
# This method will be called by our monkey-patched Jekyll::Cleaner#new_files
|
34
|
+
# in place of the single-destination method usually used.
|
35
|
+
# This allows us to tell Jekyll about more than a single file
|
36
|
+
# that should be kept when regenerating the site.
|
37
|
+
# This makes DistorteD fast!
|
38
|
+
def destinations(dest_root)
|
39
|
+
wanted_files.map{|f| File.join(dest_root, @relative_dest, f)}
|
40
|
+
end
|
41
|
+
|
42
|
+
# HACK HACK HACK
|
43
|
+
# Jekyll does not pass this method a site.dest like it does write() and
|
44
|
+
# others, but I want to be able to short-circuit here if all the
|
45
|
+
# to-be-generated files already exist.
|
46
|
+
def modified?
|
47
|
+
# Assume modified for the sake of freshness :)
|
48
|
+
modified = true
|
49
|
+
|
50
|
+
site_dest = Jekyll::DistorteD::Floor::config(:destination).to_s
|
51
|
+
if Dir.exist?(site_dest)
|
52
|
+
if Dir.exist?(File.join(site_dest, @relative_dest))
|
53
|
+
extant_files = Dir.entries(File.join(site_dest, @relative_dest)).to_set
|
54
|
+
|
55
|
+
# TODO: Make this smarter. It's not enough that all the generated
|
56
|
+
# filenames should exist. Try a few more ways to detect subtler
|
57
|
+
# "changes to the source file since generation of variations.
|
58
|
+
if wanted_files.subset?(extant_files)
|
59
|
+
Jekyll.logger.debug(@name, "All variations present: #{wanted_files}")
|
60
|
+
modified = false
|
61
|
+
else
|
62
|
+
Jekyll.logger.debug(@name, "Missing variations: #{wanted_files - extant_files}")
|
63
|
+
end
|
64
|
+
|
65
|
+
end # relative_dest.exists?
|
66
|
+
end # site_dest.exists?
|
67
|
+
Jekyll.logger.debug("#{@name} modified?", modified)
|
68
|
+
return modified
|
69
|
+
end # modified?
|
70
|
+
|
71
|
+
# Whether to write the file to the filesystem
|
72
|
+
#
|
73
|
+
# Returns true unless the defaults for the destination path from
|
74
|
+
# _config.yml contain `published: false`.
|
75
|
+
def write?
|
76
|
+
publishable = defaults.fetch('published'.freeze, true)
|
77
|
+
return publishable unless @collection
|
78
|
+
|
79
|
+
publishable && @collection.write?
|
80
|
+
end
|
81
|
+
|
82
|
+
# Write the static file to the destination directory (if modified).
|
83
|
+
#
|
84
|
+
# dest - The String path to the destination dir.
|
85
|
+
#
|
86
|
+
# Returns false if the file was not modified since last time (no-op).
|
87
|
+
def write(dest_root)
|
88
|
+
plug
|
89
|
+
return false if File.exist?(path) && !modified?
|
90
|
+
|
91
|
+
# Create any directories to the depth of the intended destination.
|
92
|
+
FileUtils.mkdir_p(File.join(dest_root, @relative_dest))
|
93
|
+
# Save every desired variation of this image.
|
94
|
+
# This will be a Set of Hashes each describing the name, type,
|
95
|
+
# dimensions, attributes, etc of each output variation we want.
|
96
|
+
# Full-size outputs will have the special tag `:full`.
|
97
|
+
files.each { |variation|
|
98
|
+
type = variation&.dig(:type)
|
99
|
+
filename = File.join(dest_root, @relative_dest, variation&.dig(:name) || @name)
|
100
|
+
|
101
|
+
if self.respond_to?(type.distorted_method)
|
102
|
+
Jekyll.logger.debug("DistorteD::#{type.distorted_method}", filename)
|
103
|
+
self.send(type.distorted_method, filename, **variation)
|
104
|
+
elsif extname == ".#{type.preferred_extension}"
|
105
|
+
Jekyll.logger.debug(@name, <<~RAWCOPY
|
106
|
+
No #{type.distorted_method} method is defined,
|
107
|
+
but the intended output type #{type.to_s} is the same
|
108
|
+
as the input type, so I will fall back to copying the raw file.
|
109
|
+
RAWCOPY
|
110
|
+
)
|
111
|
+
copy_file(filename)
|
112
|
+
else
|
113
|
+
Jekyll.logger.error(@name, "Missing rendering method #{type.distorted_method}")
|
114
|
+
raise MediaTypeOutputNotImplementedError.new(filename, type, self.class.name)
|
115
|
+
end
|
116
|
+
}
|
117
|
+
end # write
|
118
|
+
|
119
|
+
private
|
120
|
+
|
121
|
+
def copy_file(dest_path, *a, **k)
|
122
|
+
if @site.safe || Jekyll.env == "production"
|
123
|
+
FileUtils.cp(path, dest_path)
|
124
|
+
else
|
125
|
+
FileUtils.copy_entry(path, dest_path)
|
126
|
+
end
|
127
|
+
end # copy_file
|
128
|
+
|
129
|
+
# Basic file properties
|
130
|
+
|
131
|
+
# Filename without the dot-and-extension.
|
132
|
+
def basename
|
133
|
+
File.basename(@name, '.*')
|
134
|
+
end
|
135
|
+
|
136
|
+
# Returns the extname /!\ including the dot /!\
|
137
|
+
def extname
|
138
|
+
File.extname(@name)
|
139
|
+
end
|
140
|
+
|
141
|
+
# Returns last modification time for this file.
|
142
|
+
def mtime
|
143
|
+
(@modified_time ||= File.stat(path).mtime).to_i
|
144
|
+
end
|
145
|
+
|
146
|
+
# Returns source file path.
|
147
|
+
def path
|
148
|
+
@path ||= begin
|
149
|
+
# Static file is from a collection inside custom collections directory
|
150
|
+
if !@collection.nil? && !@site.config['collections_dir'.freeze].empty?
|
151
|
+
File.join(*[@base, @site.config['collections_dir'.freeze], @dir, @name].compact)
|
152
|
+
else
|
153
|
+
File.join(*[@base, @dir, @name].compact)
|
154
|
+
end
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
# Returns a Hash keyed by MIME::Type objects with value as a Set of Hashes
|
159
|
+
# describing the media's output variations to be generated for each Type.
|
160
|
+
def variations
|
161
|
+
changes(abstract(:changes)).map{ |t|
|
162
|
+
[t, outer_limits(abstract(:outer_limits)).map{ |d|
|
163
|
+
|
164
|
+
# Don't change the filename of full-size variations
|
165
|
+
tag = d&.dig(:tag) != :full ? '-'.concat(d&.dig(:tag).to_s) : ''.freeze
|
166
|
+
# Use the original extname for LastResort
|
167
|
+
ext = t == CHECKING::YOU::OUT('application/x.distorted.last-resort') ? File.extname(@name) : t.preferred_extension
|
168
|
+
# Handle LastResort for files that might be a bare name with no extension
|
169
|
+
dot = '.'.freeze unless ext.nil? || ext&.empty?
|
170
|
+
|
171
|
+
d.merge({
|
172
|
+
# e.g. 'SomeImage-medium.jpg` but just `SomeImage.jpg` and not `SomeImage-full.jpg`
|
173
|
+
# for the full-resolution outputs.
|
174
|
+
# The default `.jpeg` preferred_extension is monkey-patched to `.jpg` because lol
|
175
|
+
:name => "#{basename}#{tag}#{dot}#{ext}",
|
176
|
+
})
|
177
|
+
|
178
|
+
}]
|
179
|
+
}.to_h
|
180
|
+
end
|
181
|
+
|
182
|
+
# Returns a flat Set of Hashes that each describe one variant of
|
183
|
+
# media file output that should exist for a given input file.
|
184
|
+
def files
|
185
|
+
filez = Set[]
|
186
|
+
variations.each_pair{ |t,v|
|
187
|
+
# Merge the type in to each variation Hash since we will no longer
|
188
|
+
# have it as the key to this Set in its container Hash.
|
189
|
+
v.each{ |d| filez.add(d.merge({:type => t})) }
|
190
|
+
}
|
191
|
+
filez
|
192
|
+
end
|
193
|
+
|
194
|
+
# Returns a Set of just the String filenames we want for this media.
|
195
|
+
# This will be used by `modified?` among others.
|
196
|
+
def wanted_files
|
197
|
+
files.map{|f| f[:name]}.to_set
|
198
|
+
end
|
199
|
+
|
200
|
+
|
201
|
+
end
|
@@ -0,0 +1,79 @@
|
|
1
|
+
div.distorted {text-align: center;}
|
2
|
+
div.distorted::after {
|
3
|
+
content: '';
|
4
|
+
display: block;
|
5
|
+
clear: left;
|
6
|
+
}
|
7
|
+
div.distorted.svg {background-color: #fbfbf8;}
|
8
|
+
div.distorted.pdf > object {min-height: 76vh;}
|
9
|
+
div.distorted > video {object-fit: contain;}
|
10
|
+
div.distorted-caption {
|
11
|
+
color: #8888888;
|
12
|
+
margin-top: 0.5em;
|
13
|
+
}
|
14
|
+
div.distorted-block {
|
15
|
+
width: 100%;
|
16
|
+
clear: both;
|
17
|
+
}
|
18
|
+
div.distorted-block > div.distorted {
|
19
|
+
display: block;
|
20
|
+
box-sizing: border-box;
|
21
|
+
float: left;
|
22
|
+
border: 4px solid transparent;
|
23
|
+
margin: 0px;
|
24
|
+
text-align: center;
|
25
|
+
width: 100%;
|
26
|
+
}
|
27
|
+
@media screen and (min-width: 40em) {
|
28
|
+
div.distorted-block > div.distorted {
|
29
|
+
width: 50%;
|
30
|
+
}
|
31
|
+
div.distorted-block > div.distorted:only-child {
|
32
|
+
width: 100%;
|
33
|
+
}
|
34
|
+
div.distorted-block > div.distorted:first-child:nth-last-child(3),
|
35
|
+
div.distorted-block > div.distorted:first-child:nth-last-child(3) ~ div.distorted,
|
36
|
+
div.distorted-block > div.distorted:first-child:nth-last-child(6),
|
37
|
+
div.distorted-block > div.distorted:first-child:nth-last-child(6) ~ div.distorted,
|
38
|
+
div.distorted-block > div.distorted:first-child:nth-last-child(9),
|
39
|
+
div.distorted-block > div.distorted:first-child:nth-last-child(9) ~ div.distorted {
|
40
|
+
width: 33.3333%;
|
41
|
+
}
|
42
|
+
div.distorted-block > div.distorted:first-child:nth-last-child(5),
|
43
|
+
div.distorted-block > div.distorted:first-child:nth-last-child(5) ~ div.distorted:nth-child(2) {
|
44
|
+
width: 50%;
|
45
|
+
}
|
46
|
+
div.distorted-block > div.distorted:first-child:nth-last-child(5) ~ div.distorted {
|
47
|
+
width: 33.3333%;
|
48
|
+
}
|
49
|
+
div.distorted-block > div.distorted:first-child:nth-last-child(7) ~ div.distorted:nth-child(3),
|
50
|
+
div.distorted-block > div.distorted:first-child:nth-last-child(7) ~ div.distorted:nth-child(4),
|
51
|
+
div.distorted-block > div.distorted:first-child:nth-last-child(7) ~ div.distorted:nth-child(5) {
|
52
|
+
width: 33.3333%;
|
53
|
+
}
|
54
|
+
}
|
55
|
+
@media screen and (min-width: 76em) {
|
56
|
+
div.distorted-block > div.distorted:first-child:nth-last-child(4),
|
57
|
+
div.distorted-block > div.distorted:first-child:nth-last-child(4) ~ div.distorted,
|
58
|
+
div.distorted-block > div.distorted:first-child:nth-last-child(8),
|
59
|
+
div.distorted-block > div.distorted:first-child:nth-last-child(8) ~ div.distorted {
|
60
|
+
width: 25%;
|
61
|
+
}
|
62
|
+
div.distorted-block > div.distorted:first-child:nth-last-child(5),
|
63
|
+
div.distorted-block > div.distorted:first-child:nth-last-child(5) ~ div.distorted:nth-child(2),
|
64
|
+
div.distorted-block > div.distorted:first-child:nth-last-child(5) ~ div.distorted,
|
65
|
+
div.distorted-block > div.distorted:first-child:nth-last-child(10),
|
66
|
+
div.distorted-block > div.distorted:first-child:nth-last-child(10) ~ div.distorted {
|
67
|
+
width: 20%;
|
68
|
+
}
|
69
|
+
div.distorted-block > div.distorted:first-child:nth-last-child(7),
|
70
|
+
div.distorted-block > div.distorted:first-child:nth-last-child(7) ~ div.distorted:nth-child(2),
|
71
|
+
div.distorted-block > div.distorted:first-child:nth-last-child(7) ~ div.distorted:nth-child(3) {
|
72
|
+
width: 33.3333%;
|
73
|
+
}
|
74
|
+
div.distorted-block > div.distorted:first-child:nth-last-child(7) ~ div.distorted,
|
75
|
+
div.distorted-block > div.distorted:first-child:nth-last-child(7) ~ div.distorted:nth-child(4),
|
76
|
+
div.distorted-block > div.distorted:first-child:nth-last-child(7) ~ div.distorted:nth-child(5) {
|
77
|
+
width: 25%;
|
78
|
+
}
|
79
|
+
}
|
@@ -0,0 +1,32 @@
|
|
1
|
+
<div class="distorted font">
|
2
|
+
{%- if href != true %}
|
3
|
+
{%- capture href %}{{ path }}{{ name }}{%- endcapture -%}
|
4
|
+
{%- endif %}
|
5
|
+
{%- if alt != nil and alt != "" %}
|
6
|
+
{%- capture attr_alt %} alt="{{ alt }}"{%- endcapture -%}
|
7
|
+
{%- endif %}
|
8
|
+
{%- if title != nil and title != "" %}
|
9
|
+
{%- capture attr_title %} title="{{ title }}"{%- endcapture -%}
|
10
|
+
{%- endif %}
|
11
|
+
{%- if loading != nil and loading != "" %}
|
12
|
+
{%- capture attr_loading %} loading="{{ loading }}"{%- endcapture -%}
|
13
|
+
{%- endif %}
|
14
|
+
<a href="{{ href }}"{{ attr_title }} target="_blank">
|
15
|
+
<picture>
|
16
|
+
{%- if sources %}
|
17
|
+
{%- for source in sources %}
|
18
|
+
{%- if source.media != nil and source.media != "" %}
|
19
|
+
{%- capture attr_media %} media="{{ source.media }}"{%- endcapture -%}
|
20
|
+
{%- else %}
|
21
|
+
{%- capture attr_media %}{%- endcapture -%}
|
22
|
+
{%- endif %}
|
23
|
+
<source srcset="{{ path }}{{ source.name }}" type="{{ source.type }}"{{ attr_media }}/>
|
24
|
+
{%- endfor %}
|
25
|
+
{%- endif %}
|
26
|
+
<img src="{{ path }}{{ fallback_img }}"{{ attr_alt }}{{ attr_title }}{{ attr_loading }}/>
|
27
|
+
</picture>
|
28
|
+
</a>
|
29
|
+
{%- if caption != nil and caption != "" %}
|
30
|
+
<p class="distorted-caption">{{ caption }}</p>
|
31
|
+
{%- endif %}
|
32
|
+
</div>
|
@@ -0,0 +1,32 @@
|
|
1
|
+
<div class="distorted image">
|
2
|
+
{%- if href != true %}
|
3
|
+
{%- capture href %}{{ path }}{{ name }}{%- endcapture -%}
|
4
|
+
{%- endif %}
|
5
|
+
{%- if alt != nil and alt != "" %}
|
6
|
+
{%- capture attr_alt %} alt="{{ alt }}"{%- endcapture -%}
|
7
|
+
{%- endif %}
|
8
|
+
{%- if title != nil and title != "" %}
|
9
|
+
{%- capture attr_title %} title="{{ title }}"{%- endcapture -%}
|
10
|
+
{%- endif %}
|
11
|
+
{%- if loading != nil and loading != "" %}
|
12
|
+
{%- capture attr_loading %} loading="{{ loading }}"{%- endcapture -%}
|
13
|
+
{%- endif %}
|
14
|
+
<a href="{{ href }}"{{ attr_title }} target="_blank">
|
15
|
+
<picture>
|
16
|
+
{%- if sources %}
|
17
|
+
{%- for source in sources %}
|
18
|
+
{%- if source.media != nil and source.media != "" %}
|
19
|
+
{%- capture attr_media %} media="{{ source.media }}"{%- endcapture -%}
|
20
|
+
{%- else %}
|
21
|
+
{%- capture attr_media %}{%- endcapture -%}
|
22
|
+
{%- endif %}
|
23
|
+
<source srcset="{{ path }}{{ source.name }}" type="{{ source.type }}"{{ attr_media }}/>
|
24
|
+
{%- endfor %}
|
25
|
+
{%- endif %}
|
26
|
+
<img src="{{ path }}{{ fallback_img }}"{{ attr_alt }}{{ attr_title }}{{ attr_loading }}/>
|
27
|
+
</picture>
|
28
|
+
</a>
|
29
|
+
{%- if caption != nil and caption != "" %}
|
30
|
+
<p class="distorted-caption">{{ caption }}</p>
|
31
|
+
{%- endif %}
|
32
|
+
</div>
|
@@ -0,0 +1,20 @@
|
|
1
|
+
<div class="distorted lastresort">
|
2
|
+
{%- if href != true %}
|
3
|
+
{%- capture href %}{{ path }}{{ name }}{%- endcapture -%}
|
4
|
+
{%- endif %}
|
5
|
+
{%- if alt != nil and alt != "" %}
|
6
|
+
{%- capture attr_alt %} alt="{{ alt }}"{%- endcapture -%}
|
7
|
+
{%- endif %}
|
8
|
+
{%- if title != nil and title != "" %}
|
9
|
+
{%- capture attr_title %} title="{{ title }}"{%- endcapture -%}
|
10
|
+
{%- endif %}
|
11
|
+
{%- if loading != nil and loading != "" %}
|
12
|
+
{%- capture attr_loading %} loading="{{ loading }}"{%- endcapture -%}
|
13
|
+
{%- endif %}
|
14
|
+
<a href="{{ href }}"{{ attr_title }} target="_blank">
|
15
|
+
<img src="{{ path }}{{ name }}"{{ attr_alt }}{{ attr_title }}{{ attr_loading }}/>
|
16
|
+
</a>
|
17
|
+
{%- if caption != nil and caption != "" %}
|
18
|
+
<p class="distorted-caption">{{ caption }}</p>
|
19
|
+
{%- endif %}
|
20
|
+
</div>
|
@@ -0,0 +1,14 @@
|
|
1
|
+
<div class="distorted pdf">
|
2
|
+
{%- if title != nil and title != "" %}
|
3
|
+
{%- capture pdf_link %}{{ title }}{%- endcapture -%}
|
4
|
+
{%- elsif alt != nil and alt != "" %}
|
5
|
+
{%- capture pdf_link %}{{ alt }}{%- endcapture -%}
|
6
|
+
{%- endif %}
|
7
|
+
<object data="{{ path }}{{ name }}#{{ pdf_open_params }}" type="application/pdf" width="{{ width }}" height="{{ height }}">
|
8
|
+
<embed src="{{ path }}{{ name }}#{{ pdf_open_params }}" type="application/pdf" width="{{ width }}" height="{{ height }}"/>
|
9
|
+
<a href="{{ path }}{{ name }}#{{ pdf_open_params }}">{{ pdf_link }} [PDF]</a>
|
10
|
+
</object>
|
11
|
+
{%- if caption != nil and caption != "" %}
|
12
|
+
<p class="distorted-caption">{{ caption }}</p>
|
13
|
+
{%- endif %}
|
14
|
+
</div>
|
@@ -0,0 +1,32 @@
|
|
1
|
+
<div class="distorted svg">
|
2
|
+
{%- if href != true %}
|
3
|
+
{%- capture href %}{{ path }}{{ name }}{%- endcapture -%}
|
4
|
+
{%- endif %}
|
5
|
+
{%- if alt != nil and alt != "" %}
|
6
|
+
{%- capture attr_alt %} alt="{{ alt }}"{%- endcapture -%}
|
7
|
+
{%- endif %}
|
8
|
+
{%- if title != nil and title != "" %}
|
9
|
+
{%- capture attr_title %} title="{{ title }}"{%- endcapture -%}
|
10
|
+
{%- endif %}
|
11
|
+
{%- if loading != nil and loading != "" %}
|
12
|
+
{%- capture attr_loading %} loading="{{ loading }}"{%- endcapture -%}
|
13
|
+
{%- endif %}
|
14
|
+
<a href="{{ href }}"{{ attr_title }} target="_blank">
|
15
|
+
<picture>
|
16
|
+
{%- if sources %}
|
17
|
+
{%- for source in sources %}
|
18
|
+
{%- if source.media != nil and source.media != "" %}
|
19
|
+
{%- capture attr_media %} media="{{ source.media }}"{%- endcapture -%}
|
20
|
+
{%- else %}
|
21
|
+
{%- capture attr_media %}{%- endcapture -%}
|
22
|
+
{%- endif %}
|
23
|
+
<source srcset="{{ path }}{{ source.name }}" type="{{ source.type }}"{{ attr_media }}/>
|
24
|
+
{%- endfor %}
|
25
|
+
{%- endif %}
|
26
|
+
<img src="{{ path }}{{ fallback_img }}"{{ attr_alt }}{{ attr_title }}{{ attr_loading }}/>
|
27
|
+
</picture>
|
28
|
+
</a>
|
29
|
+
{%- if caption != nil and caption != "" %}
|
30
|
+
<p class="distorted-caption">{{ caption }}</p>
|
31
|
+
{%- endif %}
|
32
|
+
</div>
|