jekyll_picture_tag 1.14.0 → 2.0.0pre1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (78) hide show
  1. checksums.yaml +4 -4
  2. data/.envrc +2 -0
  3. data/.github/workflows/code-checks.yml +2 -12
  4. data/.rubocop.yml +2 -0
  5. data/.ruby-version +1 -1
  6. data/docs/devs/contributing/code.md +11 -3
  7. data/docs/devs/contributing/testing.md +0 -11
  8. data/docs/devs/releases.md +20 -0
  9. data/docs/index.md +32 -17
  10. data/docs/logo.png +0 -0
  11. data/docs/logo.svg +880 -0
  12. data/docs/users/getting_started.md +55 -0
  13. data/docs/users/installation.md +17 -38
  14. data/docs/users/liquid_tag/argument_reference/crop.md +21 -36
  15. data/docs/users/liquid_tag/examples.md +13 -25
  16. data/docs/users/liquid_tag/index.md +1 -1
  17. data/docs/users/notes/{migration.md → migration_1.md} +1 -1
  18. data/docs/users/notes/migration_2.md +99 -0
  19. data/docs/users/presets/cropping.md +21 -22
  20. data/docs/users/presets/default.md +11 -3
  21. data/docs/users/presets/examples.md +77 -45
  22. data/docs/users/presets/fallback_image.md +1 -1
  23. data/docs/users/presets/html_attributes.md +1 -1
  24. data/docs/users/presets/image_formats.md +3 -3
  25. data/docs/users/presets/image_quality.md +70 -55
  26. data/docs/users/presets/index.md +78 -42
  27. data/docs/users/presets/link_source.md +1 -1
  28. data/docs/users/presets/media_queries.md +1 -1
  29. data/docs/users/presets/nomarkdown_override.md +1 -1
  30. data/docs/users/presets/pixel_ratio_srcsets.md +1 -1
  31. data/docs/users/presets/width_height_attributes.md +1 -1
  32. data/docs/users/presets/width_srcsets.md +61 -23
  33. data/docs/users/tutorial.md +97 -0
  34. data/jekyll_picture_tag.gemspec +33 -23
  35. data/lib/jekyll_picture_tag.rb +8 -6
  36. data/lib/jekyll_picture_tag/cache.rb +64 -3
  37. data/lib/jekyll_picture_tag/defaults/global.rb +18 -0
  38. data/lib/jekyll_picture_tag/defaults/presets.rb +57 -0
  39. data/lib/jekyll_picture_tag/images.rb +1 -0
  40. data/lib/jekyll_picture_tag/images/generated_image.rb +25 -63
  41. data/lib/jekyll_picture_tag/images/image_file.rb +90 -0
  42. data/lib/jekyll_picture_tag/images/img_uri.rb +3 -12
  43. data/lib/jekyll_picture_tag/images/source_image.rb +44 -9
  44. data/lib/jekyll_picture_tag/instructions.rb +70 -6
  45. data/lib/jekyll_picture_tag/instructions/children/config.rb +128 -0
  46. data/lib/jekyll_picture_tag/instructions/children/context.rb +24 -0
  47. data/lib/jekyll_picture_tag/instructions/children/params.rb +90 -0
  48. data/lib/jekyll_picture_tag/instructions/children/parsers.rb +41 -0
  49. data/lib/jekyll_picture_tag/instructions/children/preset.rb +182 -0
  50. data/lib/jekyll_picture_tag/instructions/parents/conditional_instruction.rb +69 -0
  51. data/lib/jekyll_picture_tag/instructions/parents/env_instruction.rb +29 -0
  52. data/lib/jekyll_picture_tag/output_formats/basic.rb +5 -17
  53. data/lib/jekyll_picture_tag/parsers.rb +5 -0
  54. data/lib/jekyll_picture_tag/{instructions → parsers}/arg_splitter.rb +1 -1
  55. data/lib/jekyll_picture_tag/parsers/configuration.rb +28 -0
  56. data/lib/jekyll_picture_tag/{instructions → parsers}/html_attributes.rb +1 -1
  57. data/lib/jekyll_picture_tag/parsers/preset.rb +43 -0
  58. data/lib/jekyll_picture_tag/{instructions → parsers}/tag_parser.rb +15 -12
  59. data/lib/jekyll_picture_tag/router.rb +35 -93
  60. data/lib/jekyll_picture_tag/srcsets/basic.rb +4 -10
  61. data/lib/jekyll_picture_tag/utils.rb +10 -20
  62. data/lib/jekyll_picture_tag/version.rb +1 -1
  63. data/readme.md +2 -0
  64. metadata +124 -106
  65. data/Dockerfile +0 -9
  66. data/docs/users/notes/input_checking.md +0 -6
  67. data/docs/users/presets/strip_metadata.md +0 -13
  68. data/install_imagemagick.sh +0 -23
  69. data/jekyll-picture-tag.gemspec +0 -52
  70. data/lib/jekyll-picture-tag.rb +0 -25
  71. data/lib/jekyll_picture_tag/cache/base.rb +0 -61
  72. data/lib/jekyll_picture_tag/cache/generated.rb +0 -20
  73. data/lib/jekyll_picture_tag/cache/source.rb +0 -19
  74. data/lib/jekyll_picture_tag/defaults/global.yml +0 -13
  75. data/lib/jekyll_picture_tag/defaults/presets.yml +0 -12
  76. data/lib/jekyll_picture_tag/instructions/configuration.rb +0 -121
  77. data/lib/jekyll_picture_tag/instructions/preset.rb +0 -122
  78. data/lib/jekyll_picture_tag/instructions/set.rb +0 -75
@@ -1,5 +1,5 @@
1
1
  ---
2
- sort: 10
2
+ sort: 11
3
3
  ---
4
4
 
5
5
  # Source Image Link
@@ -1,5 +1,5 @@
1
1
  ---
2
- sort: 1
2
+ sort: 2
3
3
  ---
4
4
 
5
5
  # Media Queries
@@ -1,5 +1,5 @@
1
1
  ---
2
- sort: 11
2
+ sort: 12
3
3
  ---
4
4
 
5
5
  # Nomarkdown Override
@@ -1,5 +1,5 @@
1
1
  ---
2
- sort: 4
2
+ sort: 5
3
3
  ---
4
4
 
5
5
  # Pixel Ratio Srcsets
@@ -1,5 +1,5 @@
1
1
  ---
2
- sort: 7
2
+ sort: 8
3
3
  ---
4
4
 
5
5
  # Width & Height (Anti-Loading-Jank)
@@ -1,19 +1,64 @@
1
1
  ---
2
- sort: 3
2
+ sort: 4
3
3
  ---
4
4
 
5
5
  # Width Based Srcsets
6
6
 
7
- A width based srcset looks like this:
7
+ A width based srcset looks like this:
8
8
 
9
9
  ```html
10
10
  srcset="myimage-800.jpg 800w, myimage-1200.jpg 1200w, myimage-2000.jpg 2000w"
11
11
  ```
12
12
 
13
- It's the default; to use it specify a `widths` setting (or don't, for the
14
- default set), and optionally the `sizes` and `size` settings.
13
+ You should use it when the size of an image depends on the size of the screen used to show it, which
14
+ generally means anything bigger than about 300 pixels. It's the default; to use it specify a
15
+ `widths` setting (or don't, for the default set), and optionally the `sizes` and `size` settings.
15
16
 
16
- ## Widths
17
+ ## A word on sizes
18
+
19
+ The `sizes` attribute is both important, and impossible to offer good defaults for. Web browsers parse
20
+ web pages line-by-line. When they run into an external asset (such as an image) they must download,
21
+ they start that process immediately without waiting to draw the page. This means that at the point
22
+ in time when the browser must decide which image to download, it has no clue how large that image
23
+ will be on the page. The sizes attribute is how we tell it.
24
+
25
+ It doesn't have to be pixel-perfect, just close enough for the browser to make a good choice. You
26
+ can't use % (percentage width of the parent container) for the same reason we have to do this at
27
+ all. If you do not provide it, the web browser will assume the image is 100vw (100% the width of
28
+ the viewport.)
29
+
30
+ ## How to create a sizes attribute
31
+
32
+ First, Load the page and image as they will appear in the final site. (Basically write the rest of
33
+ the preset.)
34
+
35
+ Next, using either dev tools or by manipulating the browser window itself, determine how large the
36
+ image will be for all reasonable screen sizes. Organize this information into CSS measurements
37
+ (using `vw`, `vh`, `px`, `em`, or a calculation based on those units) associated with your
38
+ named CSS media queries, and enter them into the relevant preset. **Order matters**; enter these
39
+ from most to least restrictive. The browser will ignore everything after the first media query it
40
+ finds that is true.
41
+
42
+ **Example:** on my particular site, for screens 900px or smaller, inline images are the width of the
43
+ viewport minus 9px of padding on either side. For screens 901px or larger, they are a constant 862px
44
+ wide. The relevant lines in my config file look like this:
45
+
46
+ ```yml
47
+ media_queries:
48
+ full_width: 'min-width: 901px'
49
+ # (...)
50
+
51
+ presets:
52
+ default:
53
+ # (...)
54
+ sizes:
55
+ full_width: 862px
56
+ size: calc(100vw - 18px)
57
+ ```
58
+
59
+ ## Settings Reference
60
+
61
+ ### Widths
17
62
 
18
63
  _Format:_ `widths: [integer, integer, (...)]`
19
64
 
@@ -23,7 +68,7 @@ _Default_: `[400, 600, 800, 1000]`
23
68
 
24
69
  Array of image widths to generate, in pixels.
25
70
 
26
- ## Media Widths
71
+ ### Media Widths
27
72
 
28
73
  _Format:_
29
74
 
@@ -41,11 +86,11 @@ media_widths:
41
86
 
42
87
  _Default:_ `widths` setting
43
88
 
44
- If you are using art direction, there is no sense in generating desktop-size
45
- files for your mobile image. You can specify sets of widths to associate with
46
- given media queries. If not specified, will use `widths` setting.
89
+ If you are using art direction, there is no sense in generating desktop-size files for your mobile
90
+ image. Similarly, there's no sense in generating 300px wide versions of your ultrawide crop. You can
91
+ specify sets of widths to associate with given media queries.
47
92
 
48
- ## Sizes
93
+ ### Sizes
49
94
 
50
95
  _Format:_
51
96
 
@@ -64,22 +109,15 @@ sizes:
64
109
  desktop: 900px
65
110
  ```
66
111
 
67
- Conditional sizes, used to construct the `sizes=` HTML attribute telling the
68
- browser how wide your image will be (on the screen) when a given media query
69
- is true. CSS dimensions can be given in `px`, `em`, or `vw`. To be used along
70
- with a width-based srcset.
71
-
72
- Provide these in order of most restrictive to least restrictive. The browser
73
- will choose the first one with an applicable media query.
74
-
75
- You don't have to provide a sizes attribute at all. If you don't, the browser
76
- will assume the image is 100% the width of the viewport.
112
+ Conditional sizes, used to construct the `sizes=` HTML attribute telling the browser how wide your
113
+ image will be (on the screen) when a given media query is true. CSS dimensions can be given in `px`,
114
+ `em`, or `vw`. Provide these in order of most restrictive to least restrictive. The browser will
115
+ choose the first one with an applicable media query.
77
116
 
78
- ## Size
117
+ ### Size
79
118
 
80
119
  _Format:_ `size: (CSS Dimension)`
81
120
 
82
121
  _Example:_ `size: 80vw`
83
122
 
84
- Unconditional `sizes` setting, to be supplied either alone or after all
85
- conditional sizes.
123
+ Unconditional `sizes` setting, to be supplied either alone or after all conditional sizes.
@@ -0,0 +1,97 @@
1
+ ---
2
+ sort: 3
3
+ ---
4
+
5
+ # Tutorial
6
+
7
+ ## Hello, world!
8
+
9
+ Once you've followed the [installation](installation) instructions, it's a good
10
+ time to make sure we're set up correctly. Drop an image or two in the site root
11
+ (or `source` directory if you [configured it](configuration/directories)), pick
12
+ some page and write the following (substitute the image filename as
13
+ appropriate):
14
+
15
+ {% raw %}
16
+ ```
17
+ {% picture my_image.jpg %}
18
+ ```
19
+ {% endraw %}
20
+
21
+ Build/serve the site and check it out! Your image should be there, and if you inspect it with the
22
+ dev tools you should see an `<img>` tag with a `srcset` attribute. You're officially serving
23
+ responsive images.
24
+
25
+ ## Webp
26
+
27
+ JPT includes several built-in presets and media queries, documented in the
28
+ [examples](presets/examples). They're intended as a starting point and a learning tool, not for
29
+ production use. Don't dig to deeply into that link just yet, try them out first:
30
+
31
+ {% raw %}
32
+ ```
33
+ {% picture jpt-webp my_image.jpg %}
34
+ ```
35
+ {% endraw %}
36
+
37
+ Now instead of a lone `<img>` tag, you get a `<picture>` surrounding two `<source>`s and an `<img>`.
38
+ The first source contains webp images, and the second contains jpgs. Success! Lighthouse is happier
39
+ and happier.
40
+
41
+ ## Alt text
42
+
43
+ Good web developers add alt text. JPT makes this easy:
44
+
45
+ {% raw %}
46
+ ```
47
+ {% picture my_image.jpg --alt Happy Puppy %}
48
+ ```
49
+ {% endraw %}
50
+
51
+ ## Crop
52
+
53
+
54
+ {% raw %}
55
+ ```
56
+ {% picture my_image.jpg 16:9 %}
57
+ ```
58
+ {% endraw %}
59
+
60
+ Feeling cinematic? If you don't like how the image gets cropped, you can adjust it:
61
+
62
+ {% raw %}
63
+ ```
64
+ {% picture my_image.jpg 16:9 center %}
65
+ ```
66
+ {% endraw %}
67
+
68
+ Your options are `attention` (which is the default), `entropy`, and `center`.
69
+
70
+ ## Art Direction
71
+
72
+ (Usually means "Cropping, but only sometimes.")
73
+
74
+ Art direction is tricky to understand; I know it tripped me up for awhile when learning the subject.
75
+ Here's a short explanation, along with a demo: Let's pretend that we have some image which looks
76
+ good on desktop, but on a mobile screen it's hard to see the subject. Resolution isn't the problem,
77
+ the image just needs to be cropped for smaller screens. JPT makes this easy:
78
+
79
+ {% raw %}
80
+ ```
81
+ {% picture my_image.jpg 2:1 jpt-mobile: my_image.jpg 1:1 %}
82
+ ```
83
+ {% endraw %}
84
+
85
+ This tag is pretty complicated, so here's a breakdown in plain english:
86
+ * Use the default preset.
87
+ * use my_image.jpg as the base image.
88
+ * Crop it to a 2:1 aspect ratio.
89
+ * When the media query named 'jpt-mobile' is true, also use my_image.jpg
90
+ * but this time crop it square.
91
+
92
+ Now adjust the browser width. When skinny, you should see a square crop of your image, and when it's
93
+ wide you should see a 2:1 crop of the same image. That's art direction. Note that there's no
94
+ requirement at all for them to be the same image, and you don't have to use JPT to do the cropping.
95
+
96
+ There are several more liquid tag examples [here](liquid_tag/examples) that you may want to look
97
+ over, as well as the [liquid tag instructions](liquid_tag).
@@ -4,48 +4,58 @@ require 'jekyll_picture_tag/version'
4
4
 
5
5
  Gem::Specification.new do |spec|
6
6
  spec.name = 'jekyll_picture_tag'
7
- spec.version = PictureTag::VERSION
8
7
  spec.authors = ['Robert Wierzbowski', 'Brendan Tobolaski',
9
8
  'Robert Buchberger']
10
9
  spec.email = ['robert@buchberger.cc']
11
-
10
+ spec.homepage = 'https://github.com/rbuchberger/jekyll_picture_tag'
11
+ spec.metadata = { 'documentation_uri' =>
12
+ 'https://rbuchberger.github.io/jekyll_picture_tag/' }
13
+ spec.license = 'BSD-3-Clause'
12
14
  spec.summary = 'Easy responsive images for Jekyll.'
13
15
  spec.description = <<-HEREDOC
14
- Jekyll Picture Tag is a liquid tag that adds responsive images to your
15
- Jekyll static site.Jekyll Picture Tag automatically creates resized source
16
- images, is fully configurable, and covers all use cases including art
17
- direction and resolution switching — with a little YAML configuration and a
18
- simple template tag.
16
+ Jekyll Picture Tag adds responsive images to your Jekyll static site. It
17
+ automatically creates resized source images, is fully configurable, and
18
+ covers all use cases, including art direction and resolution switching, with
19
+ a little YAML configuration and a simple template tag.
19
20
  HEREDOC
20
- spec.homepage = 'https://github.com/rbuchberger/jekyll_picture_tag'
21
- spec.license = 'BSD-3-Clause'
22
- spec.require_paths = ['lib']
23
21
 
22
+ spec.version = PictureTag::VERSION
23
+ spec.require_paths = ['lib']
24
24
  spec.files = `git ls-files -z`.split("\x0").reject do |f|
25
- f.match(%r{^(test|spec|features)/})
25
+ f.match(%r{^(test)/})
26
26
  end
27
27
 
28
- spec.required_ruby_version = ['>= 2.5', '< 3']
29
-
28
+ spec.required_ruby_version = ['>= 2.6', '< 3']
29
+
30
+ # addressable is used to url-encode image filenames.
31
+ spec.add_runtime_dependency 'addressable', '~> 2.6'
32
+ # Jekyll versions older than 4.0 are not supported.
33
+ spec.add_runtime_dependency 'jekyll', '~> 4.0'
34
+ # MIME types are needed for <source> tags' type= attributes.
35
+ spec.add_runtime_dependency 'mime-types', '~> 3.0'
36
+ # objective_elements handles HTML generation.
37
+ spec.add_runtime_dependency 'objective_elements', '~> 1.1'
38
+ # rainbow is used to colorize terminal output.
39
+ spec.add_runtime_dependency 'rainbow', '~> 3.0'
40
+ # ruby-vips interfaces with libvips.
41
+ spec.add_runtime_dependency 'ruby-vips', '~> 2.0.17'
42
+
43
+ # libvips handles all image processing operations.
44
+ spec.requirements << 'libvips'
45
+
46
+ # Development dependencies are not installed when using this gem. You can
47
+ # ignore these, unless you are working on JPT itself.
30
48
  spec.add_development_dependency 'bundler', '~> 2.0'
31
- spec.add_development_dependency 'minitest', '~> 5.11'
49
+ spec.add_development_dependency 'minitest', '~> 5.14'
32
50
  spec.add_development_dependency 'minitest-rg'
33
51
  spec.add_development_dependency 'mocha', '~> 1.9'
34
- spec.add_development_dependency 'nokogiri', '~> 1.10'
52
+ spec.add_development_dependency 'nokogiri', '~> 1.1'
35
53
  spec.add_development_dependency 'pry'
36
54
  spec.add_development_dependency 'rake', '~> 12.3'
37
55
  spec.add_development_dependency 'rubocop', '~> 1.7.0'
38
56
  spec.add_development_dependency 'rubocop-minitest', '~> 0.10.0'
39
57
  spec.add_development_dependency 'rubocop-performance', '~> 1.9.0'
40
58
  spec.add_development_dependency 'rubocop-rake', '~> 0.5.0'
41
-
42
59
  spec.add_development_dependency 'simplecov', '~> 0.20.0'
43
60
  spec.add_development_dependency 'solargraph'
44
-
45
- spec.add_dependency 'addressable', '~> 2.6'
46
- spec.add_dependency 'mime-types', '~> 3.0'
47
- spec.add_dependency 'mini_magick', '~> 4.0'
48
- spec.add_dependency 'objective_elements', '~> 1.1'
49
-
50
- spec.add_runtime_dependency 'jekyll', '< 5'
51
61
  end
@@ -5,9 +5,12 @@ require_relative 'jekyll_picture_tag/cache'
5
5
  require_relative 'jekyll_picture_tag/images'
6
6
  require_relative 'jekyll_picture_tag/instructions'
7
7
  require_relative 'jekyll_picture_tag/output_formats'
8
+ require_relative 'jekyll_picture_tag/parsers'
8
9
  require_relative 'jekyll_picture_tag/router'
9
10
  require_relative 'jekyll_picture_tag/srcsets'
10
11
  require_relative 'jekyll_picture_tag/utils'
12
+ require_relative 'jekyll_picture_tag/defaults/presets'
13
+ require_relative 'jekyll_picture_tag/defaults/global'
11
14
 
12
15
  # Title: Jekyll Picture Tag
13
16
  # Authors: Rob Wierzbowski : @robwierzbowski
@@ -50,7 +53,6 @@ module PictureTag
50
53
  # care about the params (arguments passed to the liquid tag). Jekyll makes
51
54
  # no attempt to parse them; they're given as a string.
52
55
  def initialize(tag_name, raw_params, tokens)
53
- Utils.warning 'You have called JPT without any arguments.' if raw_params.empty?
54
56
  @raw_params = raw_params
55
57
  super
56
58
  end
@@ -61,7 +63,9 @@ module PictureTag
61
63
  def render(context)
62
64
  setup(context)
63
65
 
64
- if PictureTag.disabled? || @raw_params.empty?
66
+ if PictureTag.disabled? || PictureTag.raw_params.empty?
67
+ Utils.warning 'You have called JPT without any arguments.'
68
+
65
69
  ''
66
70
  else
67
71
  PictureTag.output_class.new.to_s
@@ -71,11 +75,9 @@ module PictureTag
71
75
  private
72
76
 
73
77
  def setup(context)
78
+ PictureTag.clear_instructions
74
79
  PictureTag.context = context
75
-
76
- # Now that we have both the tag parameters and the context object, we can
77
- # build our instruction set.
78
- PictureTag.instructions = Instructions::Set.new(@raw_params)
80
+ PictureTag.raw_params = @raw_params
79
81
 
80
82
  # We need to explicitly prevent jekyll from overwriting our generated
81
83
  # image files:
@@ -1,3 +1,64 @@
1
- require_relative 'cache/base'
2
- require_relative 'cache/source'
3
- require_relative 'cache/generated'
1
+ require 'json'
2
+
3
+ module PictureTag
4
+ # Store expensive bits of information between text files. Originally cached
5
+ # width & heights of images in addition to digests, now just image digests.
6
+ class Cache
7
+ def initialize(base_name)
8
+ @base_name = base_name
9
+ end
10
+
11
+ def [](key)
12
+ data[key]
13
+ end
14
+
15
+ def []=(key, value)
16
+ raise ArgumentError unless template.keys.include? key
17
+
18
+ data[key] = value
19
+ end
20
+
21
+ # Call after updating data.
22
+ def write
23
+ return if PictureTag.config['disable_disk_cache']
24
+
25
+ FileUtils.mkdir_p(File.join(base_directory, sub_directory))
26
+
27
+ File.open(filename, 'w+') do |f|
28
+ f.write JSON.generate(data)
29
+ end
30
+ end
31
+
32
+ private
33
+
34
+ def data
35
+ @data ||= if File.exist?(filename)
36
+ JSON.parse(File.read(filename)).transform_keys(&:to_sym)
37
+ else
38
+ template
39
+ end
40
+ end
41
+
42
+ # /home/dave/my_blog/.jekyll-cache/jpt/(cache_dir)/assets/myimage.jpg.json
43
+ # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
44
+ def base_directory
45
+ File.join(PictureTag.site.cache_dir, 'jpt')
46
+ end
47
+
48
+ # /home/dave/my_blog/.jekyll-cache/jpt/(cache_dir)/assets/myimage.jpg.json
49
+ # ^^^^^^^^
50
+ def sub_directory
51
+ File.dirname(@base_name)
52
+ end
53
+
54
+ # /home/dave/my_blog/.jekyll-cache/jpt/somefolder/myimage.jpg.json
55
+ # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
56
+ def filename
57
+ File.join(base_directory, @base_name + '.json')
58
+ end
59
+
60
+ def template
61
+ { digest: nil }
62
+ end
63
+ end
64
+ end