jekyll_picture_tag 1.11.0 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.envrc +4 -0
- data/.github/workflows/code-checks.yml +33 -0
- data/.gitignore +3 -0
- data/.rubocop.yml +31 -3
- data/.ruby-version +1 -1
- data/docs/.envrc +2 -0
- data/docs/Gemfile +4 -2
- data/docs/Gemfile.lock +14 -12
- data/docs/_config.yml +6 -10
- data/docs/devs/contributing/code.md +54 -0
- data/docs/devs/contributing/docs.md +31 -0
- data/docs/devs/contributing/index.md +15 -0
- data/docs/devs/contributing/setup.md +33 -0
- data/docs/devs/contributing/testing.md +23 -0
- data/docs/devs/index.md +7 -0
- data/docs/devs/releases.md +118 -0
- data/docs/index.md +67 -31
- data/docs/logo.png +0 -0
- data/docs/logo.svg +880 -0
- data/docs/users/configuration/directories.md +34 -0
- data/docs/users/configuration/disable.md +24 -0
- data/docs/users/configuration/fast_build.md +28 -0
- data/docs/users/configuration/ignore_missing.md +23 -0
- data/docs/users/configuration/index.md +29 -0
- data/docs/users/configuration/kramdown_fix.md +20 -0
- data/docs/users/configuration/suppress_warnings.md +16 -0
- data/docs/users/configuration/urls.md +69 -0
- data/docs/users/getting_started.md +55 -0
- data/docs/users/index.md +7 -0
- data/docs/users/installation.md +32 -0
- data/docs/users/liquid_tag/argument_reference/alternate_images.md +18 -0
- data/docs/users/liquid_tag/argument_reference/attributes.md +42 -0
- data/docs/users/liquid_tag/argument_reference/base_image.md +12 -0
- data/docs/users/liquid_tag/argument_reference/crop.md +33 -0
- data/docs/users/liquid_tag/argument_reference/link.md +16 -0
- data/docs/users/liquid_tag/argument_reference/preset.md +17 -0
- data/docs/users/liquid_tag/argument_reference/readme.md +9 -0
- data/docs/users/liquid_tag/examples.md +81 -0
- data/docs/users/liquid_tag/index.md +31 -0
- data/docs/users/notes/git_lfs.md +7 -0
- data/docs/users/notes/github_pages.md +5 -0
- data/docs/users/notes/html_attributes.md +5 -0
- data/docs/users/notes/index.md +6 -0
- data/docs/users/notes/kramdown_bug.md +41 -0
- data/docs/users/notes/managing_images.md +21 -0
- data/docs/{migration.md → users/notes/migration_1.md} +1 -1
- data/docs/users/notes/migration_2.md +99 -0
- data/docs/users/presets/cropping.md +60 -0
- data/docs/users/presets/default.md +32 -0
- data/docs/users/presets/examples.md +111 -0
- data/docs/users/presets/fallback_image.md +28 -0
- data/docs/users/presets/html_attributes.md +26 -0
- data/docs/users/presets/image_formats.md +21 -0
- data/docs/users/presets/image_quality.md +120 -0
- data/docs/users/presets/index.md +75 -0
- data/docs/users/presets/link_source.md +16 -0
- data/docs/users/presets/markup_formats/fragments.md +48 -0
- data/docs/users/presets/markup_formats/javascript_friendly.md +57 -0
- data/docs/users/presets/markup_formats/readme.md +43 -0
- data/docs/users/presets/markup_formats/standard_html.md +25 -0
- data/docs/users/presets/media_queries.md +36 -0
- data/docs/users/presets/nomarkdown_override.md +17 -0
- data/docs/users/presets/pixel_ratio_srcsets.md +32 -0
- data/docs/users/presets/quality_width_graph.png +0 -0
- data/docs/users/presets/width_height_attributes.md +34 -0
- data/docs/users/presets/width_srcsets.md +123 -0
- data/docs/users/presets/writing_presets.md +65 -0
- data/docs/users/tutorial.md +97 -0
- data/jekyll_picture_tag.gemspec +38 -23
- data/lib/jekyll_picture_tag.rb +11 -10
- data/lib/jekyll_picture_tag/cache.rb +64 -3
- data/lib/jekyll_picture_tag/defaults/global.rb +18 -0
- data/lib/jekyll_picture_tag/defaults/presets.rb +57 -0
- data/lib/jekyll_picture_tag/images.rb +4 -0
- data/lib/jekyll_picture_tag/images/generated_image.rb +92 -0
- data/lib/jekyll_picture_tag/images/image_file.rb +90 -0
- data/lib/jekyll_picture_tag/{img_uri.rb → images/img_uri.rb} +3 -10
- data/lib/jekyll_picture_tag/{source_image.rb → images/source_image.rb} +44 -9
- data/lib/jekyll_picture_tag/instructions.rb +70 -6
- data/lib/jekyll_picture_tag/instructions/children/config.rb +128 -0
- data/lib/jekyll_picture_tag/instructions/children/context.rb +24 -0
- data/lib/jekyll_picture_tag/instructions/children/params.rb +90 -0
- data/lib/jekyll_picture_tag/instructions/children/parsers.rb +41 -0
- data/lib/jekyll_picture_tag/instructions/children/preset.rb +182 -0
- data/lib/jekyll_picture_tag/instructions/parents/conditional_instruction.rb +69 -0
- data/lib/jekyll_picture_tag/instructions/parents/env_instruction.rb +29 -0
- data/lib/jekyll_picture_tag/output_formats/basic.rb +5 -17
- data/lib/jekyll_picture_tag/parsers.rb +5 -0
- data/lib/jekyll_picture_tag/{instructions → parsers}/arg_splitter.rb +1 -1
- data/lib/jekyll_picture_tag/parsers/configuration.rb +28 -0
- data/lib/jekyll_picture_tag/{instructions → parsers}/html_attributes.rb +1 -1
- data/lib/jekyll_picture_tag/parsers/preset.rb +43 -0
- data/lib/jekyll_picture_tag/{instructions → parsers}/tag_parser.rb +15 -12
- data/lib/jekyll_picture_tag/router.rb +35 -93
- data/lib/jekyll_picture_tag/srcsets/basic.rb +4 -10
- data/lib/jekyll_picture_tag/utils.rb +24 -20
- data/lib/jekyll_picture_tag/version.rb +1 -1
- data/readme.md +15 -13
- metadata +215 -93
- data/.travis.yml +0 -8
- data/Dockerfile +0 -9
- data/docs/_layouts/directory.html +0 -32
- data/docs/assets/style.css +0 -31
- data/docs/contributing.md +0 -109
- data/docs/example_presets.md +0 -116
- data/docs/global_configuration.md +0 -173
- data/docs/installation.md +0 -45
- data/docs/notes.md +0 -91
- data/docs/output.md +0 -63
- data/docs/presets.md +0 -391
- data/docs/releases.md +0 -70
- data/docs/usage.md +0 -157
- data/jekyll-picture-tag.gemspec +0 -52
- data/lib/jekyll-picture-tag.rb +0 -25
- data/lib/jekyll_picture_tag/cache/base.rb +0 -59
- data/lib/jekyll_picture_tag/cache/generated.rb +0 -20
- data/lib/jekyll_picture_tag/cache/source.rb +0 -19
- data/lib/jekyll_picture_tag/defaults/global.yml +0 -11
- data/lib/jekyll_picture_tag/defaults/presets.yml +0 -11
- data/lib/jekyll_picture_tag/generated_image.rb +0 -140
- data/lib/jekyll_picture_tag/instructions/configuration.rb +0 -121
- data/lib/jekyll_picture_tag/instructions/preset.rb +0 -103
- data/lib/jekyll_picture_tag/instructions/set.rb +0 -71
@@ -0,0 +1,90 @@
|
|
1
|
+
module PictureTag
|
2
|
+
# Basically a wrapper class for vips. Handles image operations.
|
3
|
+
# Vips returns new images for Crop, resize, and autorotate operations.
|
4
|
+
# Quality, metadata stripping, and format are applied on write.
|
5
|
+
class ImageFile
|
6
|
+
def initialize(source, base)
|
7
|
+
@source = source
|
8
|
+
@base = base
|
9
|
+
|
10
|
+
build
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
attr_reader :source, :base
|
16
|
+
|
17
|
+
def build
|
18
|
+
notify
|
19
|
+
|
20
|
+
mkdir
|
21
|
+
|
22
|
+
image = load_image
|
23
|
+
|
24
|
+
image = process(image)
|
25
|
+
|
26
|
+
write(image)
|
27
|
+
end
|
28
|
+
|
29
|
+
# Processing pipeline
|
30
|
+
def process(image)
|
31
|
+
image = crop(image) if source.crop?
|
32
|
+
|
33
|
+
image = resize(image)
|
34
|
+
|
35
|
+
image.autorot
|
36
|
+
end
|
37
|
+
|
38
|
+
def write_opts
|
39
|
+
opts = PictureTag.preset['image_options'][@base.format] || {}
|
40
|
+
|
41
|
+
opts[:strip] = PictureTag.preset['strip_metadata']
|
42
|
+
|
43
|
+
# gifs don't accept a quality setting.
|
44
|
+
opts[:Q] = base.quality unless base.format == 'gif'
|
45
|
+
|
46
|
+
opts.transform_keys(&:to_sym)
|
47
|
+
end
|
48
|
+
|
49
|
+
def load_image
|
50
|
+
Vips::Image.new_from_file source.name
|
51
|
+
end
|
52
|
+
|
53
|
+
def write(image)
|
54
|
+
begin
|
55
|
+
image.write_to_file(base.absolute_filename, **write_opts)
|
56
|
+
rescue Vips::Error
|
57
|
+
# If vips can't handle it, fall back to imagemagick.
|
58
|
+
opts = write_opts.transform_keys do |key|
|
59
|
+
key == :Q ? :quality : key
|
60
|
+
end
|
61
|
+
|
62
|
+
image.magicksave(base.absolute_filename, **opts)
|
63
|
+
end
|
64
|
+
|
65
|
+
# Fix permissions. TODO - still necessary?
|
66
|
+
FileUtils.chmod(0o644, base.absolute_filename)
|
67
|
+
end
|
68
|
+
|
69
|
+
def notify
|
70
|
+
puts 'Generating new image file: ' + base.name
|
71
|
+
end
|
72
|
+
|
73
|
+
def resize(image)
|
74
|
+
image.resize(scale_value)
|
75
|
+
end
|
76
|
+
|
77
|
+
def crop(image)
|
78
|
+
image.smartcrop(*source.dimensions,
|
79
|
+
interesting: PictureTag.keep(@source.media_preset))
|
80
|
+
end
|
81
|
+
|
82
|
+
def scale_value
|
83
|
+
base.width.to_f / source.width
|
84
|
+
end
|
85
|
+
|
86
|
+
def mkdir
|
87
|
+
FileUtils.mkdir_p(File.dirname(base.absolute_filename))
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
@@ -18,7 +18,7 @@ module PictureTag
|
|
18
18
|
# | domain | baseurl | directory | filename
|
19
19
|
def to_s
|
20
20
|
Addressable::URI.escape(
|
21
|
-
File.join(domain, baseurl, directory, @filename)
|
21
|
+
File.join(domain, PictureTag.baseurl, directory, @filename)
|
22
22
|
)
|
23
23
|
end
|
24
24
|
|
@@ -29,21 +29,14 @@ module PictureTag
|
|
29
29
|
# | domain | baseurl | j-p-t output dir | filename
|
30
30
|
def domain
|
31
31
|
if PictureTag.cdn?
|
32
|
-
PictureTag.
|
33
|
-
elsif PictureTag.
|
32
|
+
PictureTag.cdn_url
|
33
|
+
elsif PictureTag.relative_url
|
34
34
|
''
|
35
35
|
else
|
36
36
|
PictureTag.config['url'] || ''
|
37
37
|
end
|
38
38
|
end
|
39
39
|
|
40
|
-
# https://example.com/my-base-path/assets/generated-images/image.jpg
|
41
|
-
# ^^^^^^^^^^^^^
|
42
|
-
# | domain | baseurl | directory | filename
|
43
|
-
def baseurl
|
44
|
-
PictureTag.config['baseurl'] || ''
|
45
|
-
end
|
46
|
-
|
47
40
|
# https://example.com/my-base-path/assets/generated-images/image.jpg
|
48
41
|
# ^^^^^^^^^^^^^^^^^^^^^^^^
|
49
42
|
# | domain | baseurl | directory | filename
|
@@ -5,7 +5,7 @@ module PictureTag
|
|
5
5
|
class SourceImage
|
6
6
|
attr_reader :shortname, :missing, :media_preset
|
7
7
|
|
8
|
-
include MiniMagick
|
8
|
+
# include MiniMagick
|
9
9
|
|
10
10
|
def initialize(relative_filename, media_preset = nil)
|
11
11
|
# /home/dave/my_blog/assets/images/somefolder/myimage.jpg
|
@@ -21,12 +21,38 @@ module PictureTag
|
|
21
21
|
@digest ||= cache[:digest] || ''
|
22
22
|
end
|
23
23
|
|
24
|
+
def crop
|
25
|
+
PictureTag.crop(media_preset)
|
26
|
+
end
|
27
|
+
|
28
|
+
def crop?
|
29
|
+
!crop.nil?
|
30
|
+
end
|
31
|
+
|
32
|
+
def keep
|
33
|
+
PictureTag.keep(media_preset)
|
34
|
+
end
|
35
|
+
|
36
|
+
def dimensions
|
37
|
+
[width, height]
|
38
|
+
end
|
39
|
+
|
24
40
|
def width
|
25
|
-
|
41
|
+
return raw_width unless crop?
|
42
|
+
|
43
|
+
[raw_width, (raw_height * cropped_aspect)].min.round
|
26
44
|
end
|
27
45
|
|
28
46
|
def height
|
29
|
-
|
47
|
+
return raw_height unless crop?
|
48
|
+
|
49
|
+
[raw_height, (raw_width / cropped_aspect)].min.round
|
50
|
+
end
|
51
|
+
|
52
|
+
def cropped_aspect
|
53
|
+
return Utils.aspect_float(raw_width, raw_height) unless crop?
|
54
|
+
|
55
|
+
Utils.aspect_float(*crop.split(':').map(&:to_f))
|
30
56
|
end
|
31
57
|
|
32
58
|
# /home/dave/my_blog/assets/images/somefolder/myimage.jpg
|
@@ -44,13 +70,23 @@ module PictureTag
|
|
44
70
|
# /home/dave/my_blog/assets/images/somefolder/myimage.jpg
|
45
71
|
# ^^^
|
46
72
|
def ext
|
47
|
-
@ext ||= File.extname(name)[1
|
73
|
+
@ext ||= File.extname(name)[1..].downcase
|
48
74
|
end
|
49
75
|
|
50
76
|
private
|
51
77
|
|
78
|
+
# pre-crop
|
79
|
+
def raw_width
|
80
|
+
@raw_width ||= @missing ? 999_999 : image.width
|
81
|
+
end
|
82
|
+
|
83
|
+
# pre-crop
|
84
|
+
def raw_height
|
85
|
+
@raw_height ||= @missing ? 999_999 : image.height
|
86
|
+
end
|
87
|
+
|
52
88
|
def cache
|
53
|
-
@cache ||= Cache
|
89
|
+
@cache ||= Cache.new(@shortname)
|
54
90
|
end
|
55
91
|
|
56
92
|
def missing?
|
@@ -75,14 +111,12 @@ module PictureTag
|
|
75
111
|
|
76
112
|
def update_cache
|
77
113
|
cache[:digest] = source_digest
|
78
|
-
cache[:width] = image.width
|
79
|
-
cache[:height] = image.height
|
80
114
|
|
81
115
|
cache.write
|
82
116
|
end
|
83
117
|
|
84
118
|
def image
|
85
|
-
@image ||= Image.
|
119
|
+
@image ||= Vips::Image.new_from_file(name)
|
86
120
|
end
|
87
121
|
|
88
122
|
def source_digest
|
@@ -90,7 +124,8 @@ module PictureTag
|
|
90
124
|
end
|
91
125
|
|
92
126
|
def missing_image_warning
|
93
|
-
"JPT Could not find #{name}.
|
127
|
+
"JPT Could not find #{name}. " \
|
128
|
+
'Your site will have broken images. Continuing.'
|
94
129
|
end
|
95
130
|
|
96
131
|
def missing_image_error
|
@@ -1,6 +1,70 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
1
|
+
module PictureTag
|
2
|
+
# Instructions obtain, validate, and typecast/coerce input values. These
|
3
|
+
# inputs are either taken directly from jekyll's inputs, or handled by parsers
|
4
|
+
# first.
|
5
|
+
#
|
6
|
+
# Logic which affects only a single setting belongs in Instructions, while
|
7
|
+
# logic which affects multiple settings belongs in Parsers.
|
8
|
+
#
|
9
|
+
# Since instruction classes are so small, we define several per file in the
|
10
|
+
# instructions directory to save on boilerplate. All fall under the
|
11
|
+
# Instructions module namespace.
|
12
|
+
module Instructions
|
13
|
+
# Generic instruction, meant to be inherited. Children of this class must
|
14
|
+
# override the source method, and likely want to override valid?, coerce,
|
15
|
+
# and error_message as applicable.
|
16
|
+
class Instruction
|
17
|
+
# Memoized value of the given instruction. This is the public API.
|
18
|
+
def value
|
19
|
+
return @value if defined?(@value)
|
20
|
+
|
21
|
+
raise ArgumentError, error_message unless valid?
|
22
|
+
|
23
|
+
@value = coerced
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
# Source(s) of truth - where does this setting come from? Logic does not
|
29
|
+
# belong here. If information comes from muliple places, return an array
|
30
|
+
# or a hash.
|
31
|
+
def source
|
32
|
+
raise NotImplementedError
|
33
|
+
end
|
34
|
+
|
35
|
+
# Determine whether or not the input(s) are valid.
|
36
|
+
def valid?
|
37
|
+
true
|
38
|
+
end
|
39
|
+
|
40
|
+
# Convert input(s) to output.
|
41
|
+
def coerce
|
42
|
+
source
|
43
|
+
end
|
44
|
+
|
45
|
+
# Message returned if validation fails. Override this with something more
|
46
|
+
# helpful.
|
47
|
+
def error_message
|
48
|
+
"JPT - #{setting_name} received an invalid argument: #{source}"
|
49
|
+
end
|
50
|
+
|
51
|
+
def coerced
|
52
|
+
return @coerced if defined?(@coerced)
|
53
|
+
|
54
|
+
@coerced = coerce
|
55
|
+
end
|
56
|
+
|
57
|
+
def setting_name
|
58
|
+
Utils.snakeize(self.class.to_s.split('::').last)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
# Load Parents
|
65
|
+
Dir[File.dirname(__FILE__) + '/instructions/parents/*.rb']
|
66
|
+
.sort.each { |file| require file }
|
67
|
+
|
68
|
+
# Load children:
|
69
|
+
Dir[File.dirname(__FILE__) + '/instructions/children/*.rb']
|
70
|
+
.sort.each { |file| require file }
|
@@ -0,0 +1,128 @@
|
|
1
|
+
module PictureTag
|
2
|
+
module Instructions
|
3
|
+
# PictureTag configuration in _config.yml
|
4
|
+
class Pconfig < Instruction
|
5
|
+
def source
|
6
|
+
PictureTag.config['picture']
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
# https://example.com/my-base-path/assets/generated-images/image.jpg
|
11
|
+
# ^^^^^^^^^^^^^
|
12
|
+
# | domain | baseurl | directory | filename
|
13
|
+
class Baseurl < Instruction
|
14
|
+
def source
|
15
|
+
{
|
16
|
+
ignore: PictureTag.pconfig['ignore_baseurl'],
|
17
|
+
key: PictureTag.pconfig['baseurl_key']
|
18
|
+
}
|
19
|
+
end
|
20
|
+
|
21
|
+
def coerce
|
22
|
+
return '' if source[:ignore]
|
23
|
+
|
24
|
+
PictureTag.config[source[:key]] || ''
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
# Whether to use relative or absolute URLs for images.
|
29
|
+
class RelativeUrl < EnvInstruction
|
30
|
+
def source
|
31
|
+
PictureTag.pconfig['relative_url']
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
# Image source directory
|
36
|
+
class SourceDir < Instruction
|
37
|
+
private
|
38
|
+
|
39
|
+
def source
|
40
|
+
[
|
41
|
+
PictureTag.site.source,
|
42
|
+
PictureTag.pconfig['source']
|
43
|
+
]
|
44
|
+
end
|
45
|
+
|
46
|
+
def coerce
|
47
|
+
File.join(*source.map(&:to_s))
|
48
|
+
end
|
49
|
+
|
50
|
+
def setting_name
|
51
|
+
'source directory'
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
# Image output directory
|
56
|
+
class DestDir < Instruction
|
57
|
+
private
|
58
|
+
|
59
|
+
def source
|
60
|
+
[
|
61
|
+
PictureTag.site.config['destination'],
|
62
|
+
PictureTag.pconfig['output']
|
63
|
+
]
|
64
|
+
end
|
65
|
+
|
66
|
+
def coerce
|
67
|
+
File.join(*source.map(&:to_s))
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
# Whether to continue if a source image is missing
|
72
|
+
class ContinueOnMissing < EnvInstruction
|
73
|
+
def source
|
74
|
+
PictureTag.pconfig['ignore_missing_images']
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
# Whether to use a CDN
|
79
|
+
class Cdn < EnvInstruction
|
80
|
+
def source
|
81
|
+
{
|
82
|
+
url: PictureTag.pconfig['cdn_url'],
|
83
|
+
setting: PictureTag.pconfig['cdn_environments']
|
84
|
+
}
|
85
|
+
end
|
86
|
+
|
87
|
+
def coerce
|
88
|
+
source[:url] && super
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
# CDN URL
|
93
|
+
class CdnUrl < Instruction
|
94
|
+
def source
|
95
|
+
PictureTag.pconfig['cdn_url']
|
96
|
+
end
|
97
|
+
|
98
|
+
def valid?
|
99
|
+
require 'uri'
|
100
|
+
uri = URI(source)
|
101
|
+
|
102
|
+
# If the URI library can't parse it, it's not valid.
|
103
|
+
uri.scheme && uri.host
|
104
|
+
end
|
105
|
+
|
106
|
+
def error_message
|
107
|
+
<<~HEREDOC
|
108
|
+
cdn_url must be a valid URI in the following format: https://example.com/
|
109
|
+
current setting: #{source}
|
110
|
+
HEREDOC
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
# Disable JPT?
|
115
|
+
class Disabled < EnvInstruction
|
116
|
+
def source
|
117
|
+
PictureTag.pconfig['disabled']
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
# Fast build?
|
122
|
+
class FastBuild < EnvInstruction
|
123
|
+
def source
|
124
|
+
PictureTag.pconfig['fast_build']
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module PictureTag
|
2
|
+
module Instructions
|
3
|
+
# Jekyll site info
|
4
|
+
class Site < Instruction
|
5
|
+
def source
|
6
|
+
PictureTag.context.registers[:site]
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
# Current page in jekyll site
|
11
|
+
class Page < Instruction
|
12
|
+
def source
|
13
|
+
PictureTag.context.registers[:page]
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
# Digs into jekyll context, returns current environment
|
18
|
+
class JekyllEnv < Instruction
|
19
|
+
def source
|
20
|
+
PictureTag.context.environments.first['jekyll']['environment']
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|