jekyll-imagemagick 1.3.1 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +22 -6
- data/Rakefile +14 -8
- data/jekyll-imagemagick.gemspec +6 -4
- data/lib/jekyll-imagemagick.rb +13 -8
- data/lib/jekyll-imagemagick/convert.rb +38 -0
- data/lib/jekyll-imagemagick/defaults.rb +15 -25
- data/lib/jekyll-imagemagick/generator.rb +141 -0
- data/lib/jekyll-imagemagick/version.rb +1 -1
- metadata +37 -9
- data/lib/jekyll-imagemagick/imageConvert.rb +0 -41
- data/lib/jekyll-imagemagick/imageGenerator.rb +0 -140
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5c64fdb90cf309d2bbf890326728d9908c0742febe8aaddc0049acb290b68be4
|
4
|
+
data.tar.gz: 7fc024aa2f2dd56147ae8f225c27d872b1c68fc1f6b0611f82bc2b6dc46cc364
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a59fe562fc23a276b8b50235cdced0dde3593afebbcba159d475ba74b14fa5603e71b2dfea4acd50d5ad51fa035ee84ced578801f098f6eb70edb67ed9dd61be
|
7
|
+
data.tar.gz: ed6d5a102f467f4a61af967ebf38103999547c9888e440c944c9d8094c6c2b640833b092a7eab881fec2ebc9ef238bcc98fbac27db644b5d9152a49912200f36
|
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
[](https://rubygems.org/gems/jekyll-imagemagick)
|
2
2
|
[](https://rubygems.org/gems/jekyll-imagemagick)
|
3
|
-
[](https://gitlab.com/emmmile/jekyll-imagemagick/pipelines)
|
4
4
|
<!-- [](https://codeclimate.com/github/sverrirs/jekyll-imagemagick) -->
|
5
5
|
<!-- [](https://hakiri.io/github/sverrirs/jekyll-imagemagick/master) -->
|
6
6
|
|
@@ -8,23 +8,34 @@
|
|
8
8
|
|
9
9
|
`jekyll-imagemagick` is a plugin for Jekyll that can automatically convert images from one format to another.
|
10
10
|
|
11
|
-
Typical usecase is having a directory full of original files or RAW images (say in PNG or other lossless formats) and convert them automatically to responsive JPG/WEBP format.
|
11
|
+
Typical usecase is having a directory full of original files or RAW images (say in PNG or other lossless formats) and convert them automatically to responsive JPG/WEBP format. I personally use this plugin in combination with Jekyll to generate images for my website [emilio.photography](https://emilio.photography/).
|
12
12
|
|
13
13
|
## Installation
|
14
14
|
|
15
|
-
|
15
|
+
You need to install [imagemagick](https://www.imagemagick.org/script/index.php) command line as a prerequisite for the generator to work.
|
16
|
+
|
17
|
+
For manual installation you can just:
|
18
|
+
|
19
|
+
```bash
|
16
20
|
gem install jekyll-imagemagick
|
17
21
|
```
|
18
22
|
|
19
|
-
|
23
|
+
Alternatively you should add `jekyll-imagemagick` to your `Gemfile` and to Jekyll's `_config.yml` (see below for the configuration).
|
20
24
|
|
21
|
-
|
25
|
+
Then install it and run Jekyll:
|
26
|
+
|
27
|
+
```bash
|
28
|
+
bundle install --path vendor/bundle
|
29
|
+
bundle exec jekyll serve
|
30
|
+
```
|
31
|
+
|
32
|
+
And you should see the generator running during site generation.
|
22
33
|
|
23
34
|
## Example configuration
|
24
35
|
|
25
36
|
The plugin can be configured in the site's `_config.yml` file, in a `imagemagick` block:
|
26
37
|
|
27
|
-
```
|
38
|
+
```yml
|
28
39
|
imagemagick:
|
29
40
|
enabled: true
|
30
41
|
widths:
|
@@ -64,12 +75,17 @@ Not all browsers are compatible with WEBP. Using the `<picture>` element and spe
|
|
64
75
|
|
65
76
|
## Development
|
66
77
|
|
78
|
+
Feel free to submit pull requests for adding new features, I'll be more than happy to review them.
|
79
|
+
Please run the tests and the codestyle checks before doing that:
|
80
|
+
|
67
81
|
```bash
|
68
82
|
bundle install --path vendor/bundle
|
69
83
|
bundle exec rake test
|
70
84
|
bundle exec rake codestyle
|
71
85
|
```
|
72
86
|
|
87
|
+
These tests are also executed automatically by Gitlab CI/CD (configured with [`.gitlab-ci.yml`](./.gitlab-ci.yml)).
|
88
|
+
|
73
89
|
## Known issues
|
74
90
|
|
75
91
|
So far so good.
|
data/Rakefile
CHANGED
@@ -1,17 +1,23 @@
|
|
1
1
|
require 'rake'
|
2
2
|
require 'rake/testtask'
|
3
3
|
require 'rubocop/rake_task'
|
4
|
+
require 'bundler/gem_tasks'
|
5
|
+
require 'rspec/core/rake_task'
|
4
6
|
|
5
|
-
|
6
|
-
task.libs.push 'lib'
|
7
|
-
task.libs.push 'test'
|
8
|
-
task.verbose = true
|
9
|
-
task.pattern = 'test/*_test.rb'
|
10
|
-
end
|
11
|
-
|
12
|
-
RuboCop::RakeTask.new(:codestyle) do |task|
|
7
|
+
RuboCop::RakeTask.new('codestyle') do |task|
|
13
8
|
task.options = [
|
14
9
|
'--display-cop-names',
|
15
10
|
'--fail-fast'
|
16
11
|
]
|
17
12
|
end
|
13
|
+
|
14
|
+
Rake::TestTask.new('test') do |task|
|
15
|
+
task.libs.push 'lib'
|
16
|
+
task.libs.push 'test'
|
17
|
+
task.verbose = true
|
18
|
+
task.pattern = 'test/test*.rb'
|
19
|
+
end
|
20
|
+
|
21
|
+
RSpec::Core::RakeTask.new('spec')
|
22
|
+
|
23
|
+
task 'default' => 'spec'
|
data/jekyll-imagemagick.gemspec
CHANGED
@@ -11,9 +11,9 @@ Gem::Specification.new do |spec|
|
|
11
11
|
spec.homepage = 'https://gitlab.com/emmmile/jekyll-imagemagick'
|
12
12
|
spec.license = 'MIT'
|
13
13
|
|
14
|
-
spec.summary = 'Image generator for Jekyll 3 websites'
|
15
|
-
spec.description = 'Image generator for Jekyll 3
|
16
|
-
'convert images from one format to another'
|
14
|
+
spec.summary = 'Image generator for Jekyll 3 websites.'
|
15
|
+
spec.description = 'Image generator for Jekyll 3 websites that automatically ' \
|
16
|
+
'convert images from one format to another.'
|
17
17
|
|
18
18
|
spec.files = Dir[
|
19
19
|
'CODE_OF_CONDUCT.md',
|
@@ -29,9 +29,11 @@ Gem::Specification.new do |spec|
|
|
29
29
|
spec.test_files = spec.files.grep(%r{^spec/})
|
30
30
|
spec.require_paths = ['lib']
|
31
31
|
|
32
|
+
spec.add_dependency 'jekyll', '>= 3.4'
|
32
33
|
spec.add_development_dependency 'bundler', '~> 1.15'
|
33
34
|
spec.add_development_dependency 'minitest', '~> 5.11'
|
34
35
|
spec.add_development_dependency 'rake', '~> 12.3'
|
35
|
-
spec.add_development_dependency '
|
36
|
+
spec.add_development_dependency 'rspec', '~> 3.0'
|
37
|
+
spec.add_development_dependency 'rubocop', '~> 0.59.1'
|
36
38
|
spec.add_development_dependency 'test-unit', '~> 3.2'
|
37
39
|
end
|
data/lib/jekyll-imagemagick.rb
CHANGED
@@ -1,10 +1,15 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'jekyll'
|
4
|
+
require 'fileutils'
|
2
5
|
require 'jekyll-imagemagick/defaults'
|
3
|
-
require 'jekyll-imagemagick/
|
4
|
-
require 'jekyll-imagemagick/
|
6
|
+
require 'jekyll-imagemagick/generator'
|
7
|
+
require 'jekyll-imagemagick/convert'
|
8
|
+
|
9
|
+
# For now this is a test
|
10
|
+
# module JekyllImagemagick
|
11
|
+
# autoload :ImageGenerator, 'jekyll-imagemagick/generator'
|
12
|
+
# autoload :ImageConvert, 'jekyll-imagemagick/convert'
|
13
|
+
# end
|
5
14
|
|
6
|
-
|
7
|
-
# not sure this is needed
|
8
|
-
module Imagemagick
|
9
|
-
end
|
10
|
-
end
|
15
|
+
# Liquid::Template.register_tag 'imagemagick', JekyllImagemagick
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'open3'
|
2
|
+
|
3
|
+
module JekyllImagemagick
|
4
|
+
# Class used to convert a single image to another format using imagemagick
|
5
|
+
class ImageConvert
|
6
|
+
# Executes a command and wait for the output
|
7
|
+
def self.run_cmd(cmd)
|
8
|
+
exit_code = 0
|
9
|
+
error = ''
|
10
|
+
output = ''
|
11
|
+
Open3.popen3(cmd) do |stdin, stdout, stderr, wait_thr|
|
12
|
+
stdin.close # we don't pass any input to the process
|
13
|
+
output = stdout.gets
|
14
|
+
error = stderr.gets
|
15
|
+
exit_code = wait_thr.value
|
16
|
+
end
|
17
|
+
|
18
|
+
if exit_code != 0
|
19
|
+
Jekyll.logger.error(LOG_PREFIX, "Command returned #{exit_code} with error #{error}")
|
20
|
+
end
|
21
|
+
|
22
|
+
# Return any captured return value
|
23
|
+
return [output, error]
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.run(input_file, output_file, flags, long_edge, resize_flags)
|
27
|
+
Jekyll.logger.info(LOG_PREFIX, "Generating image \"#{output_file}\"")
|
28
|
+
|
29
|
+
cmd = "convert \"#{input_file}\" #{flags} "
|
30
|
+
if long_edge != 0
|
31
|
+
cmd += "-resize \"#{long_edge}>\" #{resize_flags} "
|
32
|
+
end
|
33
|
+
cmd += "\"#{output_file}\""
|
34
|
+
Jekyll.logger.debug(LOG_PREFIX, "Running command \"#{cmd}\"")
|
35
|
+
run_cmd(cmd)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -1,32 +1,22 @@
|
|
1
|
-
module
|
2
|
-
|
3
|
-
# The default configuration for the Imagemagick generator
|
4
|
-
# The values here represent the defaults if nothing is set
|
5
|
-
# TODO
|
6
|
-
DEFAULT = {
|
7
|
-
'enabled' => false,
|
1
|
+
module JekyllImagemagick
|
2
|
+
LOG_PREFIX = 'Imagemagick:'.freeze
|
8
3
|
|
9
|
-
|
10
|
-
|
4
|
+
# The default configuration for the Imagemagick generator
|
5
|
+
# The values here represent the defaults if nothing is set
|
6
|
+
DEFAULTS = {
|
7
|
+
'enabled' => false,
|
11
8
|
|
12
|
-
|
13
|
-
|
9
|
+
# List of directories containing images to optimize, Nested directories will not be checked
|
10
|
+
'input_directories' => [],
|
14
11
|
|
15
|
-
|
16
|
-
|
12
|
+
# List of resolutions to generate, 0 means full size otherwise is the long edge
|
13
|
+
'widths' => [0],
|
17
14
|
|
18
|
-
|
19
|
-
'resize_flags' => '-filter Lanczos',
|
15
|
+
'input_formats' => ['.png', '.tiff'],
|
20
16
|
|
21
|
-
|
22
|
-
'input_formats' => ['.png', '.tiff'],
|
17
|
+
'output_formats' => [],
|
23
18
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
# List of files or directories to explicitly include
|
28
|
-
# e.g. single files outside of the main image directories
|
29
|
-
'include' => []
|
30
|
-
}.freeze
|
31
|
-
end
|
19
|
+
# List of files or directories to exclude
|
20
|
+
'exclude' => []
|
21
|
+
}.freeze
|
32
22
|
end
|
@@ -0,0 +1,141 @@
|
|
1
|
+
require 'jekyll/document'
|
2
|
+
require 'fileutils'
|
3
|
+
|
4
|
+
module JekyllImagemagick
|
5
|
+
# A static file to hold the generated webp image after generation
|
6
|
+
# so that Jekyll will copy it into the site output directory
|
7
|
+
class ImageFile < Jekyll::StaticFile
|
8
|
+
def write(_dest)
|
9
|
+
true # Recover from strange exception when starting server without --auto
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
# Go through a set of directories and convert files
|
14
|
+
class ImageGenerator < Jekyll::Generator
|
15
|
+
# This generator is safe from arbitrary code execution.
|
16
|
+
safe true
|
17
|
+
|
18
|
+
# This generator should be passive with regard to its execution
|
19
|
+
priority :lowest
|
20
|
+
|
21
|
+
# Main function, called by Jekyll-core. Do the transformations...
|
22
|
+
def generate(site)
|
23
|
+
# Retrieve and merge the configuration from the site yml file
|
24
|
+
@config = DEFAULTS.merge(site.config['imagemagick'] || {})
|
25
|
+
|
26
|
+
# If disabled then simply quit
|
27
|
+
unless @config['enabled']
|
28
|
+
Jekyll.logger.info(LOG_PREFIX, 'Disabled in site.config')
|
29
|
+
return
|
30
|
+
end
|
31
|
+
|
32
|
+
# If the site destination directory has not yet been created then create it now.
|
33
|
+
# Otherwise, we cannot write our file there.
|
34
|
+
unless File.directory? site.dest
|
35
|
+
Dir.mkdir(site.dest)
|
36
|
+
end
|
37
|
+
|
38
|
+
files = get_files_to_transform(site, @config['input_directories'], @config['input_formats'])
|
39
|
+
tuples = compute_transformations(site, files, @config['output_formats'], @config['widths'])
|
40
|
+
generate_output_paths(site, tuples)
|
41
|
+
generated_files = generate_files(site, tuples, @config['output_formats'])
|
42
|
+
|
43
|
+
Jekyll.logger.info(LOG_PREFIX, "Generated #{generated_files} file(s)")
|
44
|
+
end
|
45
|
+
|
46
|
+
private
|
47
|
+
|
48
|
+
# Return all the files to convert
|
49
|
+
def get_files_to_transform(site, directories, input_formats)
|
50
|
+
files = []
|
51
|
+
|
52
|
+
directories.each do |directory|
|
53
|
+
directory_full_path = File.join(site.source, directory)
|
54
|
+
Jekyll.logger.info(LOG_PREFIX, "Searching files in #{directory_full_path}")
|
55
|
+
|
56
|
+
Dir[directory_full_path + '**/*.*'].each do |file_full_path|
|
57
|
+
# If the file_full_path is not one of the supported formats, exit early
|
58
|
+
extension = File.extname(file_full_path).downcase
|
59
|
+
next unless input_formats.include? extension
|
60
|
+
|
61
|
+
files.push(file_full_path)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
return files
|
66
|
+
end
|
67
|
+
|
68
|
+
# Returns a list (input, output, edge)
|
69
|
+
def compute_transformations(site, input_files_full_path, formats, edges)
|
70
|
+
output = []
|
71
|
+
|
72
|
+
if formats.length.zero?
|
73
|
+
Jekyll.logger.warn(LOG_PREFIX, 'No output formats found!')
|
74
|
+
return output
|
75
|
+
end
|
76
|
+
|
77
|
+
input_files_full_path.each do |input_file_full_path|
|
78
|
+
formats.each do |format_extension, _flags|
|
79
|
+
edges.each do |edge|
|
80
|
+
extension = File.extname(input_file_full_path)
|
81
|
+
prefix = File.dirname(input_file_full_path.sub(site.source, ''))
|
82
|
+
suffix = ''
|
83
|
+
unless edge.zero?
|
84
|
+
suffix = '-' + edge.to_s
|
85
|
+
end
|
86
|
+
filename = File.basename(input_file_full_path, extension) +
|
87
|
+
suffix + '.' + format_extension.to_s
|
88
|
+
output_file_full_path = File.join(site.dest + prefix, filename)
|
89
|
+
output.push([input_file_full_path, output_file_full_path, edge])
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
return output
|
95
|
+
end
|
96
|
+
|
97
|
+
def generate_output_paths(_site, tuples)
|
98
|
+
tuples.each do |tuple|
|
99
|
+
_input, output, _edge = tuple
|
100
|
+
directory = File.dirname(output)
|
101
|
+
FileUtils.mkdir_p(directory)
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
def generate_files(site, tuples, formats)
|
106
|
+
generated_files = 0
|
107
|
+
|
108
|
+
tuples.each do |tuple|
|
109
|
+
input_file_full_path, output_file_full_path, edge = tuple
|
110
|
+
# Check if the file already has a webp alternative?
|
111
|
+
# If we're force rebuilding all webp files then ignore the check
|
112
|
+
# also check the modified time on the files to ensure that the webp file
|
113
|
+
# is newer than the source file, if not then regenerate
|
114
|
+
if !File.file?(output_file_full_path) ||
|
115
|
+
(File.mtime(output_file_full_path) <= File.mtime(input_file_full_path))
|
116
|
+
# Generate the file
|
117
|
+
extension = File.extname(output_file_full_path).sub('.', '')
|
118
|
+
ImageConvert.run(input_file_full_path,
|
119
|
+
output_file_full_path,
|
120
|
+
formats[extension],
|
121
|
+
edge,
|
122
|
+
@config['resize_flags'])
|
123
|
+
generated_files += 1
|
124
|
+
end
|
125
|
+
|
126
|
+
next unless File.file?(output_file_full_path)
|
127
|
+
|
128
|
+
# Keep the webp file from being cleaned by Jekyll
|
129
|
+
prefix = File.dirname(input_file_full_path.sub(site.source, ''))
|
130
|
+
file_path = site.dest + prefix + '/' + File.basename(output_file_full_path)
|
131
|
+
Jekyll.logger.info(LOG_PREFIX, "Adding static file #{file_path}")
|
132
|
+
site.static_files << ImageFile.new(site,
|
133
|
+
site.dest,
|
134
|
+
prefix,
|
135
|
+
File.basename(output_file_full_path))
|
136
|
+
end
|
137
|
+
|
138
|
+
return generated_files
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
metadata
CHANGED
@@ -1,15 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: jekyll-imagemagick
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Emilio Del Tessandoro
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-
|
11
|
+
date: 2018-09-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: jekyll
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '3.4'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '3.4'
|
13
27
|
- !ruby/object:Gem::Dependency
|
14
28
|
name: bundler
|
15
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -52,20 +66,34 @@ dependencies:
|
|
52
66
|
- - "~>"
|
53
67
|
- !ruby/object:Gem::Version
|
54
68
|
version: '12.3'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rspec
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '3.0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '3.0'
|
55
83
|
- !ruby/object:Gem::Dependency
|
56
84
|
name: rubocop
|
57
85
|
requirement: !ruby/object:Gem::Requirement
|
58
86
|
requirements:
|
59
87
|
- - "~>"
|
60
88
|
- !ruby/object:Gem::Version
|
61
|
-
version:
|
89
|
+
version: 0.59.1
|
62
90
|
type: :development
|
63
91
|
prerelease: false
|
64
92
|
version_requirements: !ruby/object:Gem::Requirement
|
65
93
|
requirements:
|
66
94
|
- - "~>"
|
67
95
|
- !ruby/object:Gem::Version
|
68
|
-
version:
|
96
|
+
version: 0.59.1
|
69
97
|
- !ruby/object:Gem::Dependency
|
70
98
|
name: test-unit
|
71
99
|
requirement: !ruby/object:Gem::Requirement
|
@@ -80,8 +108,8 @@ dependencies:
|
|
80
108
|
- - "~>"
|
81
109
|
- !ruby/object:Gem::Version
|
82
110
|
version: '3.2'
|
83
|
-
description: Image generator for Jekyll 3
|
84
|
-
from one format to another
|
111
|
+
description: Image generator for Jekyll 3 websites that automatically convert images
|
112
|
+
from one format to another.
|
85
113
|
email:
|
86
114
|
- emilio.deltessa@gmail.com
|
87
115
|
executables: []
|
@@ -95,9 +123,9 @@ files:
|
|
95
123
|
- Rakefile
|
96
124
|
- jekyll-imagemagick.gemspec
|
97
125
|
- lib/jekyll-imagemagick.rb
|
126
|
+
- lib/jekyll-imagemagick/convert.rb
|
98
127
|
- lib/jekyll-imagemagick/defaults.rb
|
99
|
-
- lib/jekyll-imagemagick/
|
100
|
-
- lib/jekyll-imagemagick/imageGenerator.rb
|
128
|
+
- lib/jekyll-imagemagick/generator.rb
|
101
129
|
- lib/jekyll-imagemagick/version.rb
|
102
130
|
homepage: https://gitlab.com/emmmile/jekyll-imagemagick
|
103
131
|
licenses:
|
@@ -122,5 +150,5 @@ rubyforge_project:
|
|
122
150
|
rubygems_version: 2.7.6
|
123
151
|
signing_key:
|
124
152
|
specification_version: 4
|
125
|
-
summary: Image generator for Jekyll 3 websites
|
153
|
+
summary: Image generator for Jekyll 3 websites.
|
126
154
|
test_files: []
|
@@ -1,41 +0,0 @@
|
|
1
|
-
require 'open3'
|
2
|
-
|
3
|
-
module Jekyll
|
4
|
-
module Imagemagick
|
5
|
-
# Class used to convert a single image to another format using imagemagick
|
6
|
-
class ImageConvert
|
7
|
-
# Executes a command and wait for the output
|
8
|
-
def self.run_cmd(cmd)
|
9
|
-
exit_code = 0
|
10
|
-
error = ''
|
11
|
-
output = ''
|
12
|
-
Open3.popen3(cmd) do |stdin, stdout, stderr, wait_thr|
|
13
|
-
stdin.close # we don't pass any input to the process
|
14
|
-
output = stdout.gets
|
15
|
-
error = stderr.gets
|
16
|
-
exit_code = wait_thr.value
|
17
|
-
end
|
18
|
-
|
19
|
-
if exit_code != 0
|
20
|
-
Jekyll.logger.error('Imagemagick:', "Command returned #{exit_code} with error #{error}")
|
21
|
-
end
|
22
|
-
|
23
|
-
# Return any captured return value
|
24
|
-
return [output, error]
|
25
|
-
end
|
26
|
-
|
27
|
-
def self.run(input_file, output_file, flags, long_edge, resize_flags)
|
28
|
-
# width, height = FastImage.size(input_file)
|
29
|
-
|
30
|
-
Jekyll.logger.info('Imagemagick:', "Generating image \"#{output_file}\"")
|
31
|
-
cmd = "convert \"#{input_file}\" #{flags} "
|
32
|
-
if long_edge != 0
|
33
|
-
cmd += "-resize \"#{long_edge}>\" #{resize_flags} "
|
34
|
-
end
|
35
|
-
cmd += "\"#{output_file}\""
|
36
|
-
Jekyll.logger.debug('Imagemagick:', "Running command \"#{cmd}\"")
|
37
|
-
run_cmd(cmd)
|
38
|
-
end
|
39
|
-
end
|
40
|
-
end
|
41
|
-
end
|
@@ -1,140 +0,0 @@
|
|
1
|
-
require 'jekyll/document'
|
2
|
-
require 'fileutils'
|
3
|
-
|
4
|
-
module Jekyll
|
5
|
-
module Imagemagick
|
6
|
-
# A static file to hold the generated webp image after generation
|
7
|
-
# so that Jekyll will copy it into the site output directory
|
8
|
-
class ImageFile < StaticFile
|
9
|
-
def write(_dest)
|
10
|
-
true # Recover from strange exception when starting server without --auto
|
11
|
-
end
|
12
|
-
end
|
13
|
-
|
14
|
-
# Go through a set of directories and convert files
|
15
|
-
class ImageGenerator < Generator
|
16
|
-
# This generator is safe from arbitrary code execution.
|
17
|
-
safe true
|
18
|
-
|
19
|
-
# This generator should be passive with regard to its execution
|
20
|
-
priority :lowest
|
21
|
-
|
22
|
-
# Return all the files to convert
|
23
|
-
def get_files_to_transform(site, directories, input_formats)
|
24
|
-
files = []
|
25
|
-
|
26
|
-
directories.each do |directory|
|
27
|
-
directory_full_path = File.join(site.source, directory)
|
28
|
-
Jekyll.logger.info('Imagemagick:', "Searching files in #{directory_full_path}")
|
29
|
-
|
30
|
-
Dir[directory_full_path + '**/*.*'].each do |file_full_path|
|
31
|
-
# If the file_full_path is not one of the supported formats, exit early
|
32
|
-
extension = File.extname(file_full_path).downcase
|
33
|
-
next unless input_formats.include? extension
|
34
|
-
|
35
|
-
files.push(file_full_path)
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
|
-
return files
|
40
|
-
end
|
41
|
-
|
42
|
-
# Returns a list (input, output, edge)
|
43
|
-
def compute_transformations(site, input_files_full_path, formats, edges)
|
44
|
-
output = []
|
45
|
-
|
46
|
-
if formats.length.zero?
|
47
|
-
Jekyll.logger.error('Imagemagick:', 'No output formats found')
|
48
|
-
return output
|
49
|
-
end
|
50
|
-
|
51
|
-
input_files_full_path.each do |input_file_full_path|
|
52
|
-
formats.each do |format_extension, _flags|
|
53
|
-
edges.each do |edge|
|
54
|
-
extension = File.extname(input_file_full_path)
|
55
|
-
prefix = File.dirname(input_file_full_path.sub(site.source, ''))
|
56
|
-
suffix = ''
|
57
|
-
if edge.zero?
|
58
|
-
suffix = '-' + edge.to_s
|
59
|
-
end
|
60
|
-
filename = File.basename(input_file_full_path, extension) +
|
61
|
-
suffix + '.' + format_extension.to_s
|
62
|
-
output_file_full_path = File.join(site.dest + prefix, filename)
|
63
|
-
output.push([input_file_full_path, output_file_full_path, edge])
|
64
|
-
end
|
65
|
-
end
|
66
|
-
end
|
67
|
-
|
68
|
-
return output
|
69
|
-
end
|
70
|
-
|
71
|
-
def generate_output_paths(_site, tuples)
|
72
|
-
tuples.each do |tuple|
|
73
|
-
_input, output, _edge = tuple
|
74
|
-
directory = File.dirname(output)
|
75
|
-
FileUtils.mkdir_p(directory)
|
76
|
-
end
|
77
|
-
end
|
78
|
-
|
79
|
-
def generate_files(site, tuples, formats)
|
80
|
-
generated_files = 0
|
81
|
-
|
82
|
-
tuples.each do |tuple|
|
83
|
-
input_file_full_path, output_file_full_path, edge = tuple
|
84
|
-
# Check if the file already has a webp alternative?
|
85
|
-
# If we're force rebuilding all webp files then ignore the check
|
86
|
-
# also check the modified time on the files to ensure that the webp file
|
87
|
-
# is newer than the source file, if not then regenerate
|
88
|
-
if !File.file?(output_file_full_path) ||
|
89
|
-
(File.mtime(output_file_full_path) <= File.mtime(input_file_full_path))
|
90
|
-
# Generate the file
|
91
|
-
extension = File.extname(output_file_full_path).sub('.', '')
|
92
|
-
ImageConvert.run(input_file_full_path,
|
93
|
-
output_file_full_path,
|
94
|
-
formats[extension],
|
95
|
-
edge,
|
96
|
-
@config['resize_flags'])
|
97
|
-
generated_files += 1
|
98
|
-
end
|
99
|
-
|
100
|
-
next unless File.file?(output_file_full_path)
|
101
|
-
# Keep the webp file from being cleaned by Jekyll
|
102
|
-
prefix = File.dirname(input_file_full_path.sub(site.source, ''))
|
103
|
-
file_path = site.dest + prefix + '/' + File.basename(output_file_full_path)
|
104
|
-
Jekyll.logger.info('Imagemagick:', "Adding static file #{file_path}")
|
105
|
-
site.static_files << ImageFile.new(site,
|
106
|
-
site.dest,
|
107
|
-
prefix,
|
108
|
-
File.basename(output_file_full_path))
|
109
|
-
end
|
110
|
-
|
111
|
-
return generated_files
|
112
|
-
end
|
113
|
-
|
114
|
-
# Do the transformations
|
115
|
-
def generate(site)
|
116
|
-
# Retrieve and merge the configuration from the site yml file
|
117
|
-
@config = DEFAULT.merge(site.config['imagemagick'] || {})
|
118
|
-
|
119
|
-
# If disabled then simply quit
|
120
|
-
unless @config['enabled']
|
121
|
-
Jekyll.logger.info('Imagemagick:', 'Disabled in site.config.')
|
122
|
-
return
|
123
|
-
end
|
124
|
-
|
125
|
-
# If the site destination directory has not yet been created then create it now.
|
126
|
-
# Otherwise, we cannot write our file there.
|
127
|
-
unless File.directory? site.dest
|
128
|
-
Dir.mkdir(site.dest)
|
129
|
-
end
|
130
|
-
|
131
|
-
files = get_files_to_transform(site, @config['input_directories'], @config['input_formats'])
|
132
|
-
tuples = compute_transformations(site, files, @config['output_formats'], @config['edges'])
|
133
|
-
generate_output_paths(site, tuples)
|
134
|
-
generated_files = generate_files(site, tuples, @config['output_formats'])
|
135
|
-
|
136
|
-
Jekyll.logger.info('Imagemagick:', "Generated #{generated_files} file(s)")
|
137
|
-
end
|
138
|
-
end
|
139
|
-
end
|
140
|
-
end
|