jekyll_picture_tag 1.14.0 → 2.0.0pre1

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.
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