jekyll_img 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 3b26f4329c93cd70afacb09303d63ac2d437b70b559403c0b4dfb0dbde060794
4
+ data.tar.gz: 9df636b6567ca51f02314d892a38a885032c8c320809fc4609dc83e82bcaf361
5
+ SHA512:
6
+ metadata.gz: fed0376534157a78447d4e5db766f9913833d0acddb41fb150d877ba35620f4b55fc3c89f986f695574930df89026ef4b02259f42ff71442cd3b340d595c07ec
7
+ data.tar.gz: b9ac7072163f1be7d578fe2705b75b5489c6379e5a91e30882263bb62a78dfe53dde295d8842c86e1f87b55016ba827d310af9491eb2b4f7fd84e0c584650de0
data/.rubocop.yml ADDED
@@ -0,0 +1,41 @@
1
+ AllCops:
2
+ Exclude:
3
+ - vendor/**/*
4
+ - exe/**/*
5
+ - Gemfile*
6
+ - Rakefile
7
+ NewCops: enable
8
+ TargetRubyVersion: 2.6
9
+
10
+ Layout/HashAlignment:
11
+ Enabled: false
12
+
13
+ Layout/LineLength:
14
+ Max: 150
15
+
16
+ Layout/MultilineMethodCallIndentation:
17
+ Enabled: false
18
+
19
+ Metrics/AbcSize:
20
+ Max: 40
21
+
22
+ Metrics/BlockLength:
23
+ Max: 30
24
+ Exclude:
25
+ - jekyll_img.gemspec
26
+ - spec/img_props_spec.rb
27
+
28
+ Metrics/CyclomaticComplexity:
29
+ Max: 10
30
+
31
+ Metrics/MethodLength:
32
+ Max: 30
33
+
34
+ Metrics/PerceivedComplexity:
35
+ Max: 10
36
+
37
+ Style/FrozenStringLiteralComment:
38
+ Enabled: false
39
+
40
+ Style/TrailingCommaInHashLiteral:
41
+ Enabled: false
data/CHANGELOG.md ADDED
@@ -0,0 +1,2 @@
1
+ ## 0.1.0 / 2023-01-12
2
+ * Initial version
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2020 Mike Slinn
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,173 @@
1
+ `jekyll_img`
2
+ [![Gem Version](https://badge.fury.io/rb/jekyll_img.svg)](https://badge.fury.io/rb/jekyll_img)
3
+ ===========
4
+
5
+ `Jekyll_img` is a Jekyll plugin that displays images,
6
+ and provides support for captions and URLs.
7
+
8
+ See [demo/index.html](demo/index.html) for examples.
9
+
10
+ Run the demo website by typing:
11
+ ```shell
12
+ $ demo/_bin/debug -r
13
+ ```
14
+ ... and point your web browser to http://localhost:4444
15
+
16
+
17
+ ## Usage
18
+ {% img [Options] src='path' %}
19
+
20
+ `Options` are:
21
+
22
+ - `align="left|inline|right|center"` Default value is `inline`
23
+ - `alt="Alt text"` Default value is the `caption` text, if provided
24
+ - `caption="A caption"` No default value
25
+ - `classes="class1 class2 classN"` Extra <img> classes; default is `rounded shadow`
26
+ - `id="someId"` No default value
27
+ - `nofollow` Generates `rel='nofollow'`; only applicable when `url` is specified
28
+ - `size='eighthsize|fullsize|halfsize|initial|quartersize|XXXYY|XXX%'`
29
+ Defines width of image.
30
+ - `initial` is the default behavior.
31
+ - `eighthsize`, `fullsize`, `halfsize`, and `quartersize` are relative to the enclosing tag's width.
32
+ - CSS units can also be used, for those cases `XXX` is a float and `YY` is `unit` (see below)
33
+ - `style='css goes here'` CSS style for <img>; no default
34
+ - `target='none|whatever'` Only applicable when `url` is specified; default value is `_blank`
35
+ - `title="A title"` Default value is `caption` text, if provided
36
+ - `url='https://domain.com'` No default value
37
+ - `wrapper_class='class1 class2 classN'` Extra CSS classes for wrapper <div>; no default value
38
+ - `wrapper_style='background-color: black;'` CSS style for wrapper <div>; no default value
39
+
40
+ [`unit`](https://developer.mozilla.org/en-US/docs/Learn/CSS/Building_blocks/Values_and_units#numbers_lengths_and_percentages) is one of: `Q`, `ch`, `cm`, `em`, `dvh`, `dvw`, `ex`, `in`, `lh`,
41
+ `lvh`, `lvw`, `mm`, `pc`, `px`, `pt`, `rem`, `rlh`, `svh`, `svw`, `vb`,
42
+ `vh`, `vi`, `vmax`, `vmin`, or `vw`.
43
+
44
+ CSS classes referenced by the `jekyll_img` plugin are at the bottom of [demo/assets/css/style.css](demo/assets/css/style.css). CSS marker classes are included, so CSS selectors can be used for additional styling.
45
+
46
+
47
+ ## Design
48
+ The most significant design issue was the decision that image size and formatting should not change
49
+ whether it had a caption.
50
+ HTML captions exist within a `<figure />` element, which also surrounds the image.
51
+
52
+ I also wanted to ensure that captions would wrap text under an image,
53
+ and would not be wider than the image they were associated with.
54
+
55
+ CSS behavior differs for `<figure />` and `<img />`.
56
+ For example, centering, floating right and left.
57
+ That means the CSS and where it would need to be applied are completely different for
58
+ naked `<img />` and `<figure />` tags.
59
+ Handling all possible situations of these two scenarios would significantly raise the complexity of the plugin code. I know, because I went down that rabbit hole.
60
+
61
+
62
+ ### Wrapper &lt;div /&gt;
63
+ To make the plugin code more manageable,
64
+ the plugin always encloses the generated HTML & CSS within a wrapper `<div />`.
65
+ The wrapper allows for a simple, consistent approach regardless of whether a caption is generated or not.
66
+
67
+ The wrapper width is identical to the displayed image width.
68
+ Within the wrapper `<div />`, the embedded `<img />` is displayed with `width=100%`.
69
+ If a caption is required, the generated `<figure />` only makes the space taken by the generated HTML longer;
70
+ the image width and height is not affected.
71
+
72
+ The wrapper will not exceed the width of the tag that encloses it if the `size` parameter has values `eighthsize`, `fullsize`, `halfsize`, `initial` or `quartersize`.
73
+
74
+ The wrapper's width can be defined independently of its enclosing tag by using [CSS units](https://developer.mozilla.org/en-US/docs/Learn/CSS/Building_blocks/Values_and_units#numbers_lengths_and_percentages) for the `size` parameter:
75
+ `Q`, `ch`, `cm`, `em`, `dvh`, `dvw`, `ex`, `in`, `lh`,
76
+ `lvh`, `lvw`, `mm`, `pc`, `px`, `pt`, `rem`, `rlh`, `svh`, `svw`, `vb`,
77
+ `vh`, `vi`, `vmax`, `vmin`, or `vw`.
78
+ Using CSS units means that large enough values could cause the image to exceed the width of its enclosing tag.
79
+
80
+
81
+ ## Installation
82
+
83
+ Add this line to your Jekyll project's Gemfile, within the `jekyll_plugins` group:
84
+
85
+ ```ruby
86
+ group :jekyll_plugins do
87
+ gem 'jekyll_img'
88
+ end
89
+ ```
90
+
91
+ Also add it to `_config.yml`:
92
+ ```yaml
93
+ plugins:
94
+ - jekyll_img
95
+ ```
96
+
97
+ And then execute:
98
+
99
+ $ bundle install
100
+
101
+
102
+ ## Additional Information
103
+ More information is available on
104
+ [Mike Slinn&rsquo;s website](https://www.mslinn.com/blog/2020/10/03/jekyll-plugins.html).
105
+
106
+
107
+ ## Development
108
+ After checking out the repo, run `bin/setup` to install dependencies.
109
+
110
+ You can also run `bin/console` for an interactive prompt that will allow you to experiment.
111
+
112
+
113
+ To build and install this gem onto your local machine, run:
114
+ ```shell
115
+ $ bundle exec rake install
116
+ jekyll_img 0.1.0 built to pkg/jekyll_img-0.1.0.gem.
117
+ jekyll_img (0.1.0) installed.
118
+ ```
119
+
120
+ Examine the newly built gem:
121
+ ```shell
122
+ $ gem info jekyll_img
123
+
124
+ *** LOCAL GEMS ***
125
+
126
+ jekyll_img (0.1.0)
127
+ Author: Mike Slinn
128
+ Homepage:
129
+ https://github.com/mslinn/jekyll_img
130
+ License: MIT
131
+ Installed at: /home/mslinn/.gems
132
+
133
+ Generates Jekyll logger with colored output.
134
+ ```
135
+
136
+ ### Testing
137
+ Examine the output by running:
138
+ ```shell
139
+ $ demo/_bin/debug -r
140
+ ```
141
+ ... and pointing your web browser to http://localhost:4444/
142
+
143
+ ### Unit Tests
144
+ Either run `rspec` from Visual Studio Code's *Run and Debug* environment
145
+ (<kbd>Ctrl</kbd>-<kbd>shift</kbd>-<kbd>D</kbd>) and view the *Debug Console* output,
146
+ or run it from the command line:
147
+ ```shell
148
+ $ rspec
149
+ ```
150
+
151
+ ### Build and Push to RubyGems
152
+ To release a new version,
153
+ 1. Update the version number in `version.rb`.
154
+ 2. Commit all changes to git; if you don't the next step might fail with an unexplainable error message.
155
+ 3. Run the following:
156
+ ```shell
157
+ $ bundle exec rake release
158
+ ```
159
+ The above creates a git tag for the version, commits the created tag,
160
+ and pushes the new `.gem` file to [RubyGems.org](https://rubygems.org).
161
+
162
+
163
+ ## Contributing
164
+
165
+ 1. Fork the project
166
+ 2. Create a descriptively named feature branch
167
+ 3. Add your feature
168
+ 4. Submit a pull request
169
+
170
+
171
+ ## License
172
+
173
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
data/Rakefile ADDED
@@ -0,0 +1,5 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rspec/core/rake_task'
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+ task default: :spec
@@ -0,0 +1,42 @@
1
+ require_relative 'lib/jekyll_img/version'
2
+
3
+ Gem::Specification.new do |spec| # rubocop:disable Metrics/BlockLength
4
+ github = 'https://github.com/mslinn/jekyll_img'
5
+
6
+ spec.bindir = 'exe'
7
+ spec.authors = ['Mike Slinn']
8
+ spec.email = ['mslinn@mslinn.com']
9
+ spec.files = Dir['.rubocop.yml', 'LICENSE.*', 'Rakefile', '{lib,spec}/**/*', '*.gemspec', '*.md']
10
+ spec.homepage = 'https://www.mslinn.com/blog/2020/10/03/jekyll-plugins.html#quote'
11
+ spec.license = 'MIT'
12
+ spec.metadata = {
13
+ 'allowed_push_host' => 'https://rubygems.org',
14
+ 'bug_tracker_uri' => "#{github}/issues",
15
+ 'changelog_uri' => "#{github}/CHANGELOG.md",
16
+ 'homepage_uri' => spec.homepage,
17
+ 'source_code_uri' => github,
18
+ }
19
+ spec.name = 'jekyll_img'
20
+ spec.post_install_message = <<~END_MESSAGE
21
+
22
+ Thanks for installing #{spec.name}!
23
+
24
+ END_MESSAGE
25
+ spec.require_paths = ['lib']
26
+ spec.required_ruby_version = '>= 2.6.0'
27
+ spec.summary = 'Provides a Jekyll filter that creates formatted quotes.'
28
+ spec.test_files = spec.files.grep %r{^(test|spec|features)/}
29
+ spec.version = JekyllImgVersion::VERSION
30
+
31
+ spec.add_dependency 'jekyll', '>= 3.5.0'
32
+ spec.add_dependency 'jekyll_plugin_support', '>= 0.3.0'
33
+
34
+ # spec.add_development_dependency 'debase'
35
+ spec.add_development_dependency 'rspec'
36
+ spec.add_development_dependency 'rspec-match_ignoring_whitespace'
37
+ spec.add_development_dependency 'rubocop'
38
+ # spec.add_development_dependency 'rubocop-jekyll'
39
+ spec.add_development_dependency 'rubocop-rake'
40
+ spec.add_development_dependency 'rubocop-rspec'
41
+ spec.add_development_dependency 'ruby-debug-ide'
42
+ end
@@ -0,0 +1,75 @@
1
+ # Like RoR's squish method
2
+ class String
3
+ def squish
4
+ strip.gsub(/\s+/, ' ')
5
+ end
6
+ end
7
+
8
+ # Constructs HTML img tag from properties
9
+ class ImgBuilder
10
+ def initialize(props)
11
+ props.compute_dependant_properties
12
+ @props = props
13
+ end
14
+
15
+ def to_s
16
+ @props.compute_dependant_properties
17
+ generate_wrapper
18
+ end
19
+
20
+ private
21
+
22
+ def generate_wrapper
23
+ classes = "imgWrapper #{@props.img_display} #{@props.align} #{@props.attr_size_class} #{@props.wrapper_class}".squish
24
+ result = <<~END_HTML
25
+ <div class='#{classes}' style='#{@props.attr_width_style} #{@props.wrapper_style}'>
26
+ #{"<figure>\n" if @props.caption}
27
+ #{ if @props.url
28
+ "<a href='#{@props.url}'#{@props.attr_target}#{@props.attr_nofollow} class='imgImgUrl'>#{generate_img}</a>"
29
+ else
30
+ generate_img
31
+ end
32
+ }
33
+ #{generate_figure_caption}
34
+ #{"</figure>\n" if @props.caption}
35
+ </div>
36
+ END_HTML
37
+ result.strip
38
+ end
39
+
40
+ def generate_figure_caption
41
+ return nil unless @props.caption
42
+
43
+ <<~END_CAPTION
44
+ <figcaption class='imgFigCaption #{@props.attr_size_class}'>
45
+ #{if @props.url
46
+ <<~END_URL
47
+ <a href="#{@props.url}" #{@props.attr_target} #{@props.attr_nofollow}>
48
+ #{@props.caption}
49
+ </a>
50
+ END_URL
51
+ else
52
+ @props.caption
53
+ end
54
+ }
55
+ </figcaption>
56
+ END_CAPTION
57
+ end
58
+
59
+ # See https://developer.mozilla.org/en-US/docs/Web/HTML/Element/picture
60
+ def generate_img
61
+ img_classes = @props.classes || 'rounded shadow'
62
+ <<~END_IMG
63
+ <picture#{@props.attr_id} class='imgPicture'>
64
+ <source srcset="#{@props.src}" type="image/webp">
65
+ <source srcset="#{@props.src_png}" type="image/png">
66
+ <img #{@props.attr_alt}
67
+ class="imgImg #{img_classes.squish}"
68
+ src="#{@props.src_png}"
69
+ #{@props.attr_style_img}
70
+ #{@props.attr_title}
71
+ />
72
+ </picture>
73
+ END_IMG
74
+ end
75
+ end
data/lib/img_props.rb ADDED
@@ -0,0 +1,97 @@
1
+ # Properties from user
2
+ # All methods are idempotent.
3
+ # attr_ methods can be called after compute_dependant_properties
4
+ # All methods except compute_dependant_properties can be called in any order
5
+ class ImgProperties
6
+ attr_accessor :align, :alt, :attr_wrapper_align_class, :caption, :classes, :id, :img_display, :nofollow, \
7
+ :src, :size, :style, :target, :title, :url, :wrapper_class, :wrapper_style
8
+
9
+ SIZES = %w[eighthsize fullsize halfsize initial quartersize].freeze
10
+
11
+ def attr_alt
12
+ "alt='#{@alt}'" if @alt
13
+ end
14
+
15
+ def attr_id
16
+ " id='#{@id}'" if @id
17
+ end
18
+
19
+ # <img> tag assets, except alignment classes (inline, left, center, right)
20
+ def attr_img_classes
21
+ @classes || 'rounded shadow'
22
+ end
23
+
24
+ def attr_nofollow
25
+ " rel='nofollow'" if @nofollow
26
+ end
27
+
28
+ def attr_size_class
29
+ return nil if @size.nil? || size_unit_specified?
30
+
31
+ abort "'#{@size}' is not a recognized size; must be one of #{SIZES.join(', ')}, or an explicit unit." \
32
+ unless SIZES.include?(@size)
33
+ @size
34
+ end
35
+
36
+ def attr_style_img
37
+ "style='width: 100%; #{@style}'".squish
38
+ end
39
+
40
+ def attr_target
41
+ return nil if @target == 'none'
42
+
43
+ target = @target || '_blank'
44
+ " target='#{target}'"
45
+ end
46
+
47
+ def attr_title
48
+ "title='#{@title}'" if @title && !@title.empty?
49
+ end
50
+
51
+ def attr_width_style
52
+ "width: #{@size};" if size_unit_specified?
53
+ end
54
+
55
+ def compute_dependant_properties
56
+ setup_src
57
+
58
+ @target ||= '_blank'
59
+
60
+ @img_display = @caption && @size ? 'imgBlock' : 'imgFlex'
61
+
62
+ @alt ||= @caption || @title
63
+ @title ||= @caption || @alt # rubocop:disable Naming/MemoizedInstanceVariableName
64
+ end
65
+
66
+ def src_png
67
+ abort 'src parameter was not specified' if @src.to_s.empty?
68
+
69
+ @src.gsub('.webp', '.png')
70
+ end
71
+
72
+ def self.local_path?(src)
73
+ first_char = src[0]
74
+ first_char.match?(%r{[./]})
75
+ end
76
+
77
+ private
78
+
79
+ def setup_src
80
+ @src = @src.to_s.strip
81
+ abort 'src parameter was not specified' if @src.empty?
82
+
83
+ @src = "/assets/images/#{@src}" unless ImgProperties.local_path?(@src) || url?(@src)
84
+ end
85
+
86
+ UNITS = %w[Q ch cm em dvh dvw ex in lh lvh lvw mm pc px pt rem rlh svh svw vb vh vi vmax vmin vw %].freeze
87
+
88
+ def size_unit_specified?
89
+ return false if @size.to_s.strip.empty?
90
+
91
+ @size.end_with?(*UNITS)
92
+ end
93
+
94
+ def url?(src)
95
+ src.start_with? 'http'
96
+ end
97
+ end
@@ -0,0 +1,3 @@
1
+ module JekyllImgVersion
2
+ VERSION = '0.1.0'.freeze
3
+ end
data/lib/jekyll_img.rb ADDED
@@ -0,0 +1,41 @@
1
+ require 'jekyll_plugin_support'
2
+ require 'jekyll_plugin_support_helper'
3
+ require_relative 'img_builder'
4
+ require_relative 'img_props'
5
+ require_relative 'jekyll_img/version'
6
+
7
+ # @author Copyright 2023 Michael Slinn
8
+ # @license SPDX-License-Identifier: Apache-2.0
9
+
10
+ module ImgModule
11
+ PLUGIN_NAME = 'img'.freeze
12
+ end
13
+
14
+ module Jekyll
15
+ # Plugin implementation
16
+ class Img < JekyllSupport::JekyllTag
17
+ def render_impl
18
+ props = ImgProperties.new
19
+ props.align = @helper.parameter_specified?('align') || 'inline'
20
+ props.alt = @helper.parameter_specified? 'alt'
21
+ props.caption = @helper.parameter_specified? 'caption'
22
+ props.classes = @helper.parameter_specified? 'class'
23
+ props.id = @helper.parameter_specified? 'id'
24
+ props.nofollow = @helper.parameter_specified? 'nofollow'
25
+ props.size = @helper.parameter_specified?('size') || @helper.parameter_specified?('_size')
26
+ props.src = @helper.parameter_specified? 'src'
27
+ props.style = @helper.parameter_specified? 'style'
28
+ props.target = @helper.parameter_specified? 'target'
29
+ props.title = @helper.parameter_specified? 'title'
30
+ props.url = @helper.parameter_specified? 'url'
31
+ props.wrapper_class = @helper.parameter_specified? 'wrapper_class'
32
+ props.wrapper_style = @helper.parameter_specified? 'wrapper_style'
33
+
34
+ @builder = ImgBuilder.new(props)
35
+ @builder.to_s
36
+ end
37
+ end
38
+ end
39
+
40
+ PluginMetaLogger.instance.info { "Loaded #{ImgModule::PLUGIN_NAME} v0.1.0 plugin." }
41
+ Liquid::Template.register_tag(ImgModule::PLUGIN_NAME, Jekyll::Img)
@@ -0,0 +1,64 @@
1
+ require 'rspec/match_ignoring_whitespace'
2
+ require_relative '../lib/img_builder'
3
+ require_relative '../lib/img_props'
4
+
5
+ # Test ImgProperties
6
+ class ImgPropertiesTest
7
+ RSpec.describe ImgBuilder do # rubocop:disable Metrics/BlockLength
8
+ it 'generates a default img' do
9
+ props = ImgProperties.new
10
+ props.src = 'blah.webp'
11
+ builder = ImgBuilder.new(props)
12
+ picture = <<~END_IMG
13
+ <div class='imgWrapper imgFlex' style=' '>
14
+ <picture class='imgPicture'>
15
+ <source srcset="/assets/images/blah.webp" type="image/webp">
16
+ <source srcset="/assets/images/blah.png" type="image/png">
17
+ <img class="imgImg rounded shadow"
18
+ src="/assets/images/blah.png"
19
+ style='width: 100%; '
20
+ />
21
+ </picture>
22
+ </div>
23
+ END_IMG
24
+
25
+ expect(builder.send(:generate_figure_caption)).to be nil
26
+ expect(builder.send(:generate_wrapper)).to match_ignoring_whitespace(picture)
27
+ end
28
+
29
+ it 'generates an img with size and caption' do
30
+ props = ImgProperties.new
31
+ props.caption = 'This is a caption'
32
+ props.size = '123px'
33
+ props.src = 'blah.webp'
34
+ builder = ImgBuilder.new(props)
35
+
36
+ caption = <<~END_CAPTION
37
+ <figcaption class='imgFigCaption '>
38
+ This is a caption
39
+ </figcaption>
40
+ END_CAPTION
41
+
42
+ picture = <<~END_IMG
43
+ <div class='imgWrapper imgBlock' style='width: 123px; '>
44
+ <figure>
45
+ <picture class='imgPicture'>
46
+ <source srcset="/assets/images/blah.webp" type="image/webp">
47
+ <source srcset="/assets/images/blah.png" type="image/png">
48
+ <img alt='This is a caption'
49
+ class="imgImg rounded shadow"
50
+ src="/assets/images/blah.png"
51
+ style='width: 100%; '
52
+ title='This is a caption'
53
+ />
54
+ </picture>
55
+ #{caption}
56
+ </figure>
57
+ </div>
58
+ END_IMG
59
+
60
+ expect(builder.send(:generate_figure_caption)).to match_ignoring_whitespace(caption)
61
+ expect(builder.send(:generate_wrapper)).to match_ignoring_whitespace(picture)
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,112 @@
1
+ require_relative '../lib/img_props'
2
+
3
+ # Test ImgProperties
4
+ class ImgProperitesTest
5
+ RSpec.describe ImgProperties do # rubocop:disable Metrics/BlockLength
6
+ it 'detects relative paths' do
7
+ expect(ImgProperties.local_path?('abcdef')).to be false
8
+ expect(ImgProperties.local_path?('./abc')).to be true
9
+ expect(ImgProperties.local_path?('/abc')).to be true
10
+ end
11
+
12
+ it 'has other class methods' do
13
+ props = ImgProperties.new
14
+ expect(props.send(:size_unit_specified?)).to be false
15
+ expect(props.send(:url?, 'blah')).to be false
16
+ expect(props.send(:url?, 'http://blah')).to be true
17
+ end
18
+
19
+ it 'does not generate attributes for most empty properties' do
20
+ props = ImgProperties.new
21
+ expect(props.attr_alt).to be nil
22
+ expect(props.attr_img_classes).to eq('rounded shadow')
23
+ expect(props.attr_id).to be nil
24
+ expect(props.attr_nofollow).to be nil
25
+ expect(props.attr_size_class).to be nil
26
+ expect(props.attr_style_img).to eq("style='width: 100%; '")
27
+ expect(props.attr_target).to eq(" target='_blank'")
28
+ expect(props.attr_title).to be nil
29
+ expect(props.attr_width_style).to be nil
30
+
31
+ props.compute_dependant_properties
32
+ expect(props.attr_wrapper_align_class).to eq('inline')
33
+ end
34
+
35
+ it 'raises exception if src was not specified' do
36
+ props = ImgProperties.new
37
+ expect { props.src_png }.to raise_error(SystemExit)
38
+ expect { props.send(:setup_src) }.to raise_error(SystemExit)
39
+
40
+ props.src = 'relative/path.webp'
41
+ props.send(:setup_src)
42
+ expect(props.src).to eq('/assets/images/relative/path.webp')
43
+
44
+ props.src = './local/path.webp'
45
+ props.send(:setup_src)
46
+ expect(props.src).to eq('./local/path.webp')
47
+
48
+ props.src = '/absolute/path.webp'
49
+ props.send(:setup_src)
50
+ expect(props.src).to eq('/absolute/path.webp')
51
+ end
52
+
53
+ it 'generates proper simple attributes' do # rubocop:disable Metrics/BlockLength
54
+ props = ImgProperties.new
55
+
56
+ props.alt = 'blah'
57
+ expect(props.attr_alt).to eq("alt='blah'")
58
+
59
+ props.classes = 'blah'
60
+ expect(props.attr_img_classes).to eq('blah')
61
+
62
+ props.id = 'blah'
63
+ expect(props.attr_id).to eq(" id='blah'")
64
+
65
+ props.nofollow = true
66
+ expect(props.attr_nofollow).to eq(" rel='nofollow'")
67
+
68
+ props.size = 'initial'
69
+ expect(props.attr_size_class).to eq('initial')
70
+
71
+ props.size = '100px'
72
+ expect(props.attr_size_class).to be nil
73
+ expect(props.attr_style_img).to eq("style='max-width: 100px;'")
74
+ expect(props.attr_width_style).to eq('width: 100px;')
75
+
76
+ props.size = '10%'
77
+ expect(props.attr_size_class).to be nil
78
+ expect(props.attr_style_img).to eq("style='max-width: 10%;'")
79
+ expect(props.attr_width_style).to eq('width: 10%;')
80
+
81
+ props.size = 'fullsize'
82
+ expect(props.attr_size_class).to eq('fullsize')
83
+ expect(props.attr_width_style).to be nil
84
+
85
+ props.style = 'width: 30rem;'
86
+ expect(props.attr_style_img).to eq("style='width: 30rem;'")
87
+
88
+ props.target = 'moon'
89
+ expect(props.attr_target).to eq(" target='moon'")
90
+
91
+ props.title = 'The End'
92
+ expect(props.attr_title).to eq("title='The End'")
93
+
94
+ props.size = '100px'
95
+ props.caption = 'A caption'
96
+ expect(props.attr_size_class).to be nil
97
+ expect(props.attr_width_style).to eq('width: 100px;')
98
+ end
99
+
100
+ it 'generates proper alignment attributes' do
101
+ props = ImgProperties.new
102
+
103
+ props.align = 'inline'
104
+ props.compute_dependant_properties
105
+ expect(props.attr_wrapper_align_class).to eq('inline')
106
+
107
+ props.align = 'center'
108
+ props.compute_dependant_properties
109
+ expect(props.attr_wrapper_align_class).to eq('center')
110
+ end
111
+ end
112
+ end
@@ -0,0 +1,72 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'jekyll'
4
+ require 'jekyll_plugin_logger'
5
+ require 'rspec/match_ignoring_whitespace'
6
+ require_relative '../lib/jekyll_img'
7
+
8
+ Registers = Struct.new(:page, :site)
9
+
10
+ # Mock for Collections
11
+ class Collections
12
+ def values
13
+ []
14
+ end
15
+ end
16
+
17
+ # Mock for Site
18
+ class SiteMock
19
+ attr_reader :config
20
+
21
+ def collections
22
+ Collections.new
23
+ end
24
+ end
25
+
26
+ # Mock for Liquid::ParseContent
27
+ class TestParseContext < Liquid::ParseContext
28
+ attr_reader :line_number, :registers
29
+
30
+ def initialize
31
+ super
32
+ @line_number = 123
33
+
34
+ @registers = Registers.new(
35
+ { },
36
+ SiteMock.new
37
+ )
38
+ end
39
+ end
40
+
41
+ # These tests all fail because I have not figured out how to provide a Jekyll block body to a test
42
+ class MyTest
43
+ RSpec.describe Jekyll::Img do
44
+ let(:logger) do
45
+ PluginMetaLogger.instance.new_logger(self, PluginMetaLogger.instance.config)
46
+ end
47
+
48
+ let(:parse_context) { TestParseContext.new }
49
+
50
+ let(:helper) do
51
+ JekyllPluginHelper.new(
52
+ 'img',
53
+ 'src="./blah.webp"',
54
+ logger
55
+ )
56
+ end
57
+
58
+ it 'has no cite or url' do
59
+ helper.reinitialize('src="./blah.webp"')
60
+ quote = Jekyll::Img.send(
61
+ :new,
62
+ 'img',
63
+ helper.markup.dup,
64
+ parse_context
65
+ )
66
+ result = quote.send(:render_impl, helper.markup)
67
+ expect(result).to match_ignoring_whitespace <<-END_RESULT
68
+ <img src="./blah.webp">
69
+ END_RESULT
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,11 @@
1
+ require 'jekyll'
2
+ require_relative '../lib/jekyll_img'
3
+
4
+ RSpec.configure do |config|
5
+ config.filter_run :focus
6
+ config.order = 'random'
7
+ config.run_all_when_everything_filtered = true
8
+
9
+ # See https://relishapp.com/rspec/rspec-core/docs/command-line/only-failures
10
+ config.example_status_persistence_file_path = 'spec/status_persistence.txt'
11
+ end
@@ -0,0 +1,10 @@
1
+ example_id | status | run_time |
2
+ ------------------------------- | ------ | --------------- |
3
+ ./spec/img_builder_spec.rb[1:1] | passed | 0.00073 seconds |
4
+ ./spec/img_props_spec.rb[1:1] | passed | 0.0001 seconds |
5
+ ./spec/img_props_spec.rb[1:2] | passed | 0.00008 seconds |
6
+ ./spec/img_props_spec.rb[1:3] | failed | 0.00051 seconds |
7
+ ./spec/img_props_spec.rb[1:4] | passed | 0.0011 seconds |
8
+ ./spec/img_props_spec.rb[1:5] | passed | 0.00019 seconds |
9
+ ./spec/img_props_spec.rb[1:6] | failed | 0.00008 seconds |
10
+ ./spec/jekyll_img_spec.rb[1:1] | failed | 0.00037 seconds |
metadata ADDED
@@ -0,0 +1,184 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: jekyll_img
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Mike Slinn
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2023-01-20 00:00:00.000000000 Z
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.5.0
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: 3.5.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: jekyll_plugin_support
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: 0.3.0
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: 0.3.0
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rspec-match_ignoring_whitespace
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rubocop
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rubocop-rake
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: rubocop-rspec
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: ruby-debug-ide
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ description:
126
+ email:
127
+ - mslinn@mslinn.com
128
+ executables: []
129
+ extensions: []
130
+ extra_rdoc_files: []
131
+ files:
132
+ - ".rubocop.yml"
133
+ - CHANGELOG.md
134
+ - LICENSE.txt
135
+ - README.md
136
+ - Rakefile
137
+ - jekyll_img.gemspec
138
+ - lib/img_builder.rb
139
+ - lib/img_props.rb
140
+ - lib/jekyll_img.rb
141
+ - lib/jekyll_img/version.rb
142
+ - spec/img_builder_spec.rb
143
+ - spec/img_props_spec.rb
144
+ - spec/jekyll_img_spec.rb
145
+ - spec/spec_helper.rb
146
+ - spec/status_persistence.txt
147
+ homepage: https://www.mslinn.com/blog/2020/10/03/jekyll-plugins.html#quote
148
+ licenses:
149
+ - MIT
150
+ metadata:
151
+ allowed_push_host: https://rubygems.org
152
+ bug_tracker_uri: https://github.com/mslinn/jekyll_img/issues
153
+ changelog_uri: https://github.com/mslinn/jekyll_img/CHANGELOG.md
154
+ homepage_uri: https://www.mslinn.com/blog/2020/10/03/jekyll-plugins.html#quote
155
+ source_code_uri: https://github.com/mslinn/jekyll_img
156
+ post_install_message: |2+
157
+
158
+ Thanks for installing jekyll_img!
159
+
160
+ rdoc_options: []
161
+ require_paths:
162
+ - lib
163
+ required_ruby_version: !ruby/object:Gem::Requirement
164
+ requirements:
165
+ - - ">="
166
+ - !ruby/object:Gem::Version
167
+ version: 2.6.0
168
+ required_rubygems_version: !ruby/object:Gem::Requirement
169
+ requirements:
170
+ - - ">="
171
+ - !ruby/object:Gem::Version
172
+ version: '0'
173
+ requirements: []
174
+ rubygems_version: 3.3.3
175
+ signing_key:
176
+ specification_version: 4
177
+ summary: Provides a Jekyll filter that creates formatted quotes.
178
+ test_files:
179
+ - spec/img_builder_spec.rb
180
+ - spec/img_props_spec.rb
181
+ - spec/jekyll_img_spec.rb
182
+ - spec/spec_helper.rb
183
+ - spec/status_persistence.txt
184
+ ...