jekyll-favicon-generator 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: 24b3fb7b124c03e2d0d939905a0552466982346dce15bb6e354d40060ae446c3
4
+ data.tar.gz: 912d66b372081c250437f18c8d73f9310965171c0d0415573b887534d9a502a0
5
+ SHA512:
6
+ metadata.gz: 96127209a335b1bee8edd0ef228e74ace1aa2914b7a51ff118e32f76ac380261a81baf6a9f64c8e774c136929a4b4354b2cc1984c795bab8d1dbac8e2549f4e5
7
+ data.tar.gz: 41eba8d3dccbe4f2fe2f6b399d0650436e9b46757dc655d40b1cd4f3a3aacfc65b8ab0a46083b010676c8179fd62d816879811d1bcc6982517505ebc96fd86ce
@@ -0,0 +1,62 @@
1
+ # frozen_string_literal: true
2
+
3
+ module JekyllFaviconGenerator
4
+ class Configuration < Jekyll::Configuration
5
+ # Default options. Overridden by values in _config.yml.
6
+ # Strings rather than symbols are used for compatibility with YAML.
7
+ DEFAULTS = {
8
+ "source" => nil,
9
+ "destination" => "assets/icons",
10
+ "color" => "#000000",
11
+ "background" => "#ffffff",
12
+ "icons" => [
13
+ {
14
+ "file" => "favicon.ico",
15
+ "size" => "16,24,32,48",
16
+ "ref" => nil,
17
+ },
18
+ {
19
+ "file" => "favicon-16.png",
20
+ "size" => 16,
21
+ "ref" => "link/icon",
22
+ },
23
+ {
24
+ "file" => "favicon-32.png",
25
+ "size" => 32,
26
+ "ref" => "link/icon",
27
+ },
28
+ {
29
+ "file" => "favicon.svg",
30
+ "ref" => "link/icon",
31
+ },
32
+ {
33
+ "file" => "apple-touch-icon.png",
34
+ "size" => 180,
35
+ "ref" => "link/apple-touch-icon",
36
+ },
37
+ {
38
+ "file" => "android-chrome-192.png",
39
+ "size" => 192,
40
+ "ref" => "manifest",
41
+ },
42
+ {
43
+ "file" => "android-chrome-512.png",
44
+ "size" => 512,
45
+ "ref" => "manifest",
46
+ },
47
+ ],
48
+ }.freeze
49
+
50
+ class << self
51
+ # Static: Produce a Configuration ready for use in a Site.
52
+ # It takes the input, fills in the defaults where values do not exist.
53
+ #
54
+ # user_config - a Hash or Configuration of overrides.
55
+ #
56
+ # Returns a Configuration filled with defaults.
57
+ def from(user_config)
58
+ Jekyll::Utils.deep_merge_hashes(DEFAULTS, Configuration[user_config].stringify_keys)
59
+ end
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,46 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "jekyll-favicon-generator/icon"
4
+ require "jekyll-favicon-generator/utilities"
5
+ require "jekyll-favicon-generator/vips"
6
+ require "jekyll-favicon-generator/manifest"
7
+
8
+ module JekyllFaviconGenerator
9
+ class Generator < Jekyll::Generator
10
+ include Utilities
11
+
12
+ def initialize(site)
13
+ @site = site
14
+ end
15
+
16
+ def generate(site)
17
+ @site = site
18
+
19
+ debug "Using libvips #{Vips.version}"
20
+
21
+ unless file_exists? source
22
+ error "File #{source} not found!"
23
+ return
24
+ end
25
+ info "Generating favicons from #{source}"
26
+
27
+ @site.static_files.push(*icons)
28
+ @site.pages.push(*manifests)
29
+ end
30
+
31
+ private
32
+
33
+ def icons
34
+ @icons ||= config["icons"].filter_map { |icon| Icon.new(@site, icon) if icon["file"] }
35
+ end
36
+
37
+ def manifests
38
+ return @manifests if @manifests
39
+
40
+ @manifests = []
41
+ manifest_icons = icons.select { |icon| icon.ref == :manifest }
42
+ @manifests << Manifest.new(@site, manifest_icons) unless manifest_icons.empty?
43
+ @manifests
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "jekyll-favicon-generator/utilities"
4
+
5
+ Jekyll::Hooks.register :site, :after_init do |site|
6
+ # Adds the source image to the exclude list so it's not copied directly to the output
7
+ site.exclude.push JekyllFaviconGenerator::UtilityClass.new(site).source
8
+ end
@@ -0,0 +1,152 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "vips"
4
+ require "bit-struct"
5
+
6
+ module JekyllFaviconGenerator
7
+ module Ico
8
+ # ICO file format references:
9
+ # https://en.wikipedia.org/wiki/ICO_(file_format)
10
+ # https://en.wikipedia.org/wiki/BMP_file_format
11
+ # https://docs.microsoft.com/en-us/previous-versions/ms997538(v=msdn.10)
12
+ # https://docs.microsoft.com/en-us/windows/win32/api/wingdi/ns-wingdi-bitmapinfoheader
13
+ # Various ICO files from various websites and generated by other software
14
+
15
+ extend self
16
+
17
+ def img_to_ico(src, ico, sizes)
18
+ File.open(ico, "wb") do |f|
19
+ f.write icon_dir sizes
20
+
21
+ sizes.each do |width|
22
+ height = width
23
+ f.write bitmap_info_header width, height
24
+
25
+ img = ::Vips::Image.thumbnail src, width, :height => height
26
+ img = img.flip(:vertical) # Flip the image since bitmap is stored bottom to top
27
+ img = img.colourspace :srgb # Ensure srgb colourspace
28
+ f.write bitmap_xor_mask img, width, height
29
+ f.write bitmap_and_mask img, width, height
30
+ end
31
+ end
32
+ true
33
+ end
34
+
35
+ private
36
+
37
+ BYTE = 8
38
+ WORD = 2 * BYTE
39
+ DWORD = 4 * BYTE
40
+ LONG = 4 * BYTE
41
+ BPP_COUNT = 32
42
+
43
+ # Generate the ICONDIR structure for the ICO file
44
+ def icon_dir(sizes)
45
+ count = sizes.length
46
+ offset = IconDir.round_byte_length + count * IconDirEntry.round_byte_length
47
+
48
+ dir = IconDir.new.tap do |id|
49
+ id.type = 1 # 1 => ICO
50
+ id.id_count = count
51
+ end.to_s
52
+
53
+ entries = sizes.map do |size|
54
+ entry = icon_dir_entry size, offset
55
+ offset += entry.bytes_in_res
56
+ entry.to_s
57
+ end
58
+
59
+ dir + entries.join
60
+ end
61
+
62
+ def icon_dir_entry(size, offset)
63
+ xor_rowsize = rowsize size * BPP_COUNT
64
+ and_rowsize = rowsize size
65
+ bytes = BitMapInfoHeader.round_byte_length + xor_rowsize * size + and_rowsize * size
66
+
67
+ IconDirEntry.new.tap do |ide|
68
+ ide.width = size
69
+ ide.height = size
70
+ ide.color_count = 0 # 0 => no color palette
71
+ ide.planes = 1
72
+ ide.bit_count = BPP_COUNT
73
+ ide.bytes_in_res = bytes
74
+ ide.image_offset = offset
75
+ end
76
+ end
77
+
78
+ def bitmap_info_header(width, height)
79
+ BitMapInfoHeader.new.tap do |bih|
80
+ bih.ih_size = BitMapInfoHeader.round_byte_length # size is only the header size
81
+ bih.width = width
82
+ bih.height = 2 * height # must be double height, even if no AND mask is included
83
+ bih.planes = 1
84
+ bih.bit_count = BPP_COUNT
85
+ bih.compression = 0 # 0 => none
86
+ bih.size_image = width * height * BPP_COUNT / BYTE
87
+ bih.clr_used = 0 # 0 since we don't use a palette
88
+ end
89
+ end
90
+
91
+ def bitmap_xor_mask(img, width, _height)
92
+ xor_rowsize = rowsize(width * BPP_COUNT)
93
+ arr = img.to_enum.map do |row|
94
+ # Colors are stored in ARGB format with LE order, so BGRA in the array
95
+ # Also pad rows to the required size
96
+ row.map { |r, g, b, a| [b, g, r, a] }.fill([0, 0, 0, 0], row.length..(xor_rowsize / 4 - 1))
97
+ end
98
+ arr.flatten.pack("C*")
99
+ end
100
+
101
+ def bitmap_and_mask(img, width, _height)
102
+ and_rowsize = rowsize width
103
+ arr = img.to_enum.map do |row|
104
+ # Convert alpha to 1-bit and pad rows to the required size
105
+ row.map { |_r, _g, _b, a| a.zero? && 1 || 0 }.fill(0, row.length..(and_rowsize * BYTE - 1))
106
+ end
107
+ [arr.flatten.join].pack("B*")
108
+ end
109
+
110
+ # Given a size in bits, return the size in bytes, rounded up to a multiple of 4 bytes
111
+ def rowsize(bit_size)
112
+ (bit_size + 31) / 32 * 4
113
+ end
114
+
115
+ class IconDir < BitStruct
116
+ default_options :endian => :little
117
+
118
+ pad :reserved, WORD
119
+ unsigned :type, WORD
120
+ unsigned :id_count, WORD
121
+ end
122
+
123
+ class IconDirEntry < BitStruct
124
+ default_options :endian => :little
125
+
126
+ unsigned :width, BYTE
127
+ unsigned :height, BYTE
128
+ unsigned :color_count, BYTE
129
+ pad :reserved, BYTE
130
+ unsigned :planes, WORD
131
+ unsigned :bit_count, WORD
132
+ unsigned :bytes_in_res, DWORD
133
+ unsigned :image_offset, DWORD
134
+ end
135
+
136
+ class BitMapInfoHeader < BitStruct
137
+ default_options :endian => :little
138
+
139
+ unsigned :ih_size, DWORD
140
+ signed :width, LONG
141
+ signed :height, LONG
142
+ unsigned :planes, WORD
143
+ unsigned :bit_count, WORD
144
+ unsigned :compression, DWORD
145
+ unsigned :size_image, DWORD
146
+ signed :x_pels_per_meter, LONG, :default => 3780 # 96 dpi (usually ignored)
147
+ signed :y_pels_per_meter, LONG, :default => 3780 # 96 dpi (usually ignored)
148
+ unsigned :clr_used, DWORD
149
+ unsigned :clr_important, DWORD, :default => 0 # 0 important colours (usually ignored)
150
+ end
151
+ end
152
+ end
@@ -0,0 +1,113 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "jekyll-favicon-generator/ico"
4
+ require "jekyll-favicon-generator/utilities"
5
+ require "jekyll-favicon-generator/size"
6
+ require "jekyll-favicon-generator/svg"
7
+ require "jekyll-favicon-generator/vips"
8
+
9
+ require "fileutils"
10
+
11
+ module JekyllFaviconGenerator
12
+ class Icon < Jekyll::StaticFile
13
+ include Utilities
14
+
15
+ def initialize(site, icon)
16
+ @site = site
17
+ @icon = icon
18
+
19
+ super site, site.source, dest_dir, @icon["file"]
20
+ end
21
+
22
+ def write(dest)
23
+ dest = destination dest
24
+ src = @site.in_source_dir source
25
+
26
+ FileUtils.mkdir_p(File.dirname(dest))
27
+ debug "Writing #{File.basename dest}"
28
+
29
+ case type
30
+ when :png
31
+ Vips.img_to_png src, dest, size.to_i
32
+ when :ico
33
+ Ico.img_to_ico src, dest, size.to_a
34
+ when :svg
35
+ Svg.optimize src, dest
36
+ else
37
+ warn "Unknown format for #{File.basename dest}, skipping"
38
+ false
39
+ end
40
+ end
41
+
42
+ def render_tag(url)
43
+ return if ref.nil? || ref == :manifest
44
+
45
+ attrs = attributes(url)
46
+ unless tag_name && attrs
47
+ warn "Unknown ref type for #{File.basename @icon["file"]}, skipping"
48
+ return
49
+ end
50
+
51
+ attrs = attrs.map { |k, v| "#{k}=#{v.to_s.encode(:xml => :attr)}" }
52
+
53
+ "<#{tag_name} #{attrs.join(" ")}>"
54
+ end
55
+
56
+ def type
57
+ @type ||= TYPES[File.extname(name).downcase] || :unknown
58
+ end
59
+
60
+ def mime
61
+ @mime ||= MIMES[type]
62
+ end
63
+
64
+ def size
65
+ @size ||= Size.new @icon["size"]
66
+ end
67
+
68
+ def ref
69
+ @ref ||= REFS[@icon["ref"]&.downcase]
70
+ end
71
+
72
+ private
73
+
74
+ TYPES = {
75
+ ".ico" => :ico,
76
+ ".png" => :png,
77
+ ".svg" => :svg,
78
+ }.freeze
79
+
80
+ MIMES = {
81
+ :ico => "image/x-icon",
82
+ :png => "image/png",
83
+ :svg => "image/svg+xml",
84
+ }.freeze
85
+
86
+ REFS = {
87
+ "link/icon" => :link_icon,
88
+ "link/apple-touch-icon" => :link_apple,
89
+ "manifest" => :manifest,
90
+ "webmanifest" => :manifest,
91
+ }.freeze
92
+
93
+ def tag_name
94
+ @tag_name ||= case ref
95
+ when :link_icon, :link_apple
96
+ "link"
97
+ end
98
+ end
99
+
100
+ def attributes(url)
101
+ case ref
102
+ when :link_icon
103
+ { :rel => "icon", :href => url, :sizes => (type == :svg ? "any" : size.to_s) }
104
+ when :link_apple
105
+ { :rel => "apple-touch-icon", :href => url, :sizes => size.to_s }
106
+ end
107
+ end
108
+
109
+ def dest_dir
110
+ ref ? super : ""
111
+ end
112
+ end
113
+ end
@@ -0,0 +1,49 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "jekyll-favicon-generator/utilities"
4
+
5
+ module JekyllFaviconGenerator
6
+ class Manifest < Jekyll::Page
7
+ include Utilities
8
+
9
+ def initialize(site, icons)
10
+ @site = site
11
+ @base = site.source
12
+ @dir = ""
13
+ @name = MANIFEST_NAME
14
+ @path = manifest_template
15
+
16
+ process(name)
17
+ read_yaml(site.source, name)
18
+
19
+ data.default_proc = proc do |_, key|
20
+ site.frontmatter_defaults.find(relative_path, type, key)
21
+ end
22
+ data.merge! icon_data icons
23
+
24
+ Jekyll::Hooks.trigger :pages, :post_init, self
25
+ end
26
+
27
+ private
28
+
29
+ MANIFEST_NAME = "site.webmanifest"
30
+
31
+ def manifest_template
32
+ @manifest_template ||= if file_exists? MANIFEST_NAME
33
+ site.in_source_dir MANIFEST_NAME
34
+ else
35
+ File.expand_path MANIFEST_NAME, __dir__
36
+ end
37
+ end
38
+
39
+ def icon_data(icons)
40
+ data = {}
41
+ data["icons"] = icons.map do |icon|
42
+ { "url" => icon.url, "size" => icon.size.to_s, "mime" => icon.mime }
43
+ end
44
+ data["color"] = config["color"]
45
+ data["background"] = config["background"]
46
+ data
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,17 @@
1
+ {
2
+ "name": "{{ site.title | default: site.name | default: "" }}",
3
+ "short_name": "{{ site.title | default: site.name | default: "" }}",
4
+ "icons": [
5
+ {%- for icon in page.icons %}
6
+ {
7
+ "src": "{{ icon.url | relative_url }}",
8
+ "sizes": "{{ icon.size }}",
9
+ "type": "{{ icon.mime }}"
10
+ }
11
+ {%- unless forloop.last %},{% endunless %}
12
+ {%- endfor %}
13
+ ],
14
+ "theme_color": "{{ page.color | default: "#ffffff" }}",
15
+ "background_color": "{{ page.background | default: "#000000" }}",
16
+ "display": "standalone"
17
+ }
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module JekyllFaviconGenerator
4
+ class Size
5
+ def initialize(size_str)
6
+ @size_arr = size_str.to_s.split(",").map(&:to_i)
7
+ @size_arr.reject!(&:zero?)
8
+ @size_arr = [16] if @size_arr.nil? || @size_arr.empty?
9
+ end
10
+
11
+ def to_a
12
+ @size_arr
13
+ end
14
+
15
+ def to_i
16
+ @size_arr[0]
17
+ end
18
+
19
+ def to_s
20
+ @size_arr.map { |s| "#{s}x#{s}" }.join " "
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "jekyll-favicon-generator/utilities"
4
+
5
+ require "nokogiri"
6
+ require "svg_optimizer"
7
+
8
+ module JekyllFaviconGenerator
9
+ module Svg
10
+ include Utilities
11
+ extend self
12
+
13
+ def optimize(src, dest)
14
+ unless File.extname(src).casecmp(".svg").zero?
15
+ warn "Unsupported #{File.extname(src).downcase} -> .svg for #{dest}"
16
+ return false
17
+ end
18
+
19
+ xml = Nokogiri::XML File.read(src) { |config| config.recover.noent }
20
+
21
+ SvgOptimizer::DEFAULT_PLUGINS.each { |plugin| plugin.new(xml).process }
22
+
23
+ File.open(dest, "w") do |file|
24
+ file << xml.root.to_xml(:indent => 0).delete("\n")
25
+ end
26
+ true
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "jekyll-favicon-generator/icon"
4
+ require "jekyll-favicon-generator/manifest"
5
+ require "jekyll-favicon-generator/utilities"
6
+
7
+ module JekyllFaviconGenerator
8
+ class Tag < Liquid::Tag
9
+ # Use Jekyll's native relative_url filter
10
+ include Jekyll::Filters::URLFilters
11
+ include Utilities
12
+
13
+ def render(context)
14
+ # Jekyll::Filters::URLFilters requires `@context` to be set in the environment.
15
+ @context = context
16
+ @site = context.registers[:site]
17
+
18
+ tags = @site.static_files.filter_map do |icon|
19
+ icon.render_tag relative_url icon.url if icon.is_a? Icon
20
+ end
21
+ tags += @site.pages.filter_map do |manifest|
22
+ "<link rel=\"manifest\" href=\"#{relative_url manifest.url}\">" if manifest.is_a? Manifest
23
+ end
24
+
25
+ tags.join("\n")
26
+ end
27
+ end
28
+ end
29
+
30
+ Liquid::Template.register_tag("favicons", JekyllFaviconGenerator::Tag)
@@ -0,0 +1,67 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "jekyll-favicon-generator/configuration"
4
+
5
+ module JekyllFaviconGenerator
6
+ module Utilities
7
+ extend self
8
+
9
+ # Logging functions
10
+
11
+ LOGGER_PREFIX = "Favicon Generator:"
12
+
13
+ def debug(topic = LOGGER_PREFIX, msg) # rubocop:disable Style/OptionalArguments
14
+ Jekyll.logger.debug topic, msg
15
+ end
16
+
17
+ def info(topic = LOGGER_PREFIX, msg) # rubocop:disable Style/OptionalArguments
18
+ Jekyll.logger.info topic, msg
19
+ end
20
+
21
+ def warn(topic = LOGGER_PREFIX, msg) # rubocop:disable Style/OptionalArguments
22
+ Jekyll.logger.warn topic, msg
23
+ end
24
+
25
+ def error(topic = LOGGER_PREFIX, msg) # rubocop:disable Style/OptionalArguments
26
+ Jekyll.logger.error topic, msg
27
+ end
28
+
29
+ def abort_with(topic = LOGGER_PREFIX, msg) # rubocop:disable Style/OptionalArguments
30
+ Jekyll.logger.abort_with topic, msg
31
+ end
32
+
33
+ # Parameters & defaults
34
+
35
+ def config
36
+ @config ||= Configuration.from @site.config["favicon-generator"] || {}
37
+ end
38
+
39
+ def source
40
+ @source ||= config["source"] || find_source
41
+ end
42
+
43
+ def dest_dir
44
+ @dest_dir ||= config["destination"] || ""
45
+ end
46
+
47
+ # File utilities
48
+
49
+ def file_exists?(file)
50
+ File.file? @site.in_source_dir(file)
51
+ end
52
+
53
+ def find_source
54
+ [".svg", ".png"].map { |ext| "favicon#{ext}" }.find { |file| file_exists? file }
55
+ end
56
+ end
57
+
58
+ # Class for accessing utility functions without instantiating anything bigger
59
+
60
+ class UtilityClass
61
+ include Utilities
62
+
63
+ def initialize(site)
64
+ @site = site
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module JekyllFaviconGenerator
4
+ VERSION = "0.1.0"
5
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "vips"
4
+
5
+ require "jekyll-favicon-generator/utilities"
6
+
7
+ module JekyllFaviconGenerator
8
+ module Vips
9
+ include Utilities
10
+
11
+ def self.version
12
+ "#{::Vips.version(0)}.#{::Vips.version(1)}.#{::Vips.version(2)}"
13
+ end
14
+
15
+ def self.img_to_png(src, png, size)
16
+ img = ::Vips::Image.thumbnail src, size, :height => size
17
+ img.pngsave png
18
+ true
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "jekyll"
4
+
5
+ require "jekyll-favicon-generator/generator"
6
+ require "jekyll-favicon-generator/hook"
7
+ require "jekyll-favicon-generator/tag"
8
+
9
+ module JekyllFaviconGenerator
10
+ autoload :VERSION, "jekyll-favicon-generator/version"
11
+ end
metadata ADDED
@@ -0,0 +1,136 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: jekyll-favicon-generator
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Lucas Jansen
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2022-06-13 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bit-struct
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '0.17'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '0.17'
27
+ - !ruby/object:Gem::Dependency
28
+ name: jekyll
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '3.7'
34
+ - - "<"
35
+ - !ruby/object:Gem::Version
36
+ version: '5.0'
37
+ type: :runtime
38
+ prerelease: false
39
+ version_requirements: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ version: '3.7'
44
+ - - "<"
45
+ - !ruby/object:Gem::Version
46
+ version: '5.0'
47
+ - !ruby/object:Gem::Dependency
48
+ name: nokogiri
49
+ requirement: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - "~>"
52
+ - !ruby/object:Gem::Version
53
+ version: '1.12'
54
+ type: :runtime
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - "~>"
59
+ - !ruby/object:Gem::Version
60
+ version: '1.12'
61
+ - !ruby/object:Gem::Dependency
62
+ name: ruby-vips
63
+ requirement: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - "~>"
66
+ - !ruby/object:Gem::Version
67
+ version: '2.1'
68
+ type: :runtime
69
+ prerelease: false
70
+ version_requirements: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - "~>"
73
+ - !ruby/object:Gem::Version
74
+ version: '2.1'
75
+ - !ruby/object:Gem::Dependency
76
+ name: svg_optimizer
77
+ requirement: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - "~>"
80
+ - !ruby/object:Gem::Version
81
+ version: '0.2'
82
+ type: :runtime
83
+ prerelease: false
84
+ version_requirements: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - "~>"
87
+ - !ruby/object:Gem::Version
88
+ version: '0.2'
89
+ description: A simple and fast Jekyll plugin to generate favicons from a single source
90
+ image.
91
+ email:
92
+ executables: []
93
+ extensions: []
94
+ extra_rdoc_files: []
95
+ files:
96
+ - lib/jekyll-favicon-generator.rb
97
+ - lib/jekyll-favicon-generator/configuration.rb
98
+ - lib/jekyll-favicon-generator/generator.rb
99
+ - lib/jekyll-favicon-generator/hook.rb
100
+ - lib/jekyll-favicon-generator/ico.rb
101
+ - lib/jekyll-favicon-generator/icon.rb
102
+ - lib/jekyll-favicon-generator/manifest.rb
103
+ - lib/jekyll-favicon-generator/site.webmanifest
104
+ - lib/jekyll-favicon-generator/size.rb
105
+ - lib/jekyll-favicon-generator/svg.rb
106
+ - lib/jekyll-favicon-generator/tag.rb
107
+ - lib/jekyll-favicon-generator/utilities.rb
108
+ - lib/jekyll-favicon-generator/version.rb
109
+ - lib/jekyll-favicon-generator/vips.rb
110
+ homepage: https://github.com/staticintlucas/jekyll-favicon-generator
111
+ licenses:
112
+ - MIT
113
+ metadata:
114
+ homepage_uri: https://github.com/staticintlucas/jekyll-favicon-generator
115
+ source_code_uri: https://github.com/staticintlucas/jekyll-favicon-generator
116
+ changelog_uri: https://github.com/staticintlucas/jekyll-favicon-generator/blob/main/CHANGELOG.md
117
+ post_install_message:
118
+ rdoc_options: []
119
+ require_paths:
120
+ - lib
121
+ required_ruby_version: !ruby/object:Gem::Requirement
122
+ requirements:
123
+ - - ">="
124
+ - !ruby/object:Gem::Version
125
+ version: 2.6.0
126
+ required_rubygems_version: !ruby/object:Gem::Requirement
127
+ requirements:
128
+ - - ">="
129
+ - !ruby/object:Gem::Version
130
+ version: '0'
131
+ requirements: []
132
+ rubygems_version: 3.3.15
133
+ signing_key:
134
+ specification_version: 4
135
+ summary: Favicon generator for Jekyll.
136
+ test_files: []