jekyll-favicon 0.2.9 → 1.0.0.pre.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (66) hide show
  1. checksums.yaml +4 -4
  2. data/.devcontainer/Dockerfile +20 -0
  3. data/.devcontainer/devcontainer.json +35 -0
  4. data/.github/PULL_REQUEST_TEMPLATE.md +4 -4
  5. data/.github/workflows/gem-push.yml +3 -3
  6. data/.github/workflows/test.yml +38 -0
  7. data/.gitignore +5 -0
  8. data/CHANGELOG.md +21 -0
  9. data/Gemfile +2 -0
  10. data/README.md +74 -24
  11. data/Rakefile +9 -7
  12. data/bin/console +1 -0
  13. data/config/jekyll/favicon.yml +115 -0
  14. data/config/jekyll/favicon/static_file.yml +3 -0
  15. data/config/jekyll/favicon/static_file/convertible.yml +42 -0
  16. data/config/jekyll/favicon/static_file/mutable.yml +22 -0
  17. data/config/jekyll/favicon/static_file/referenceable.yml +15 -0
  18. data/config/jekyll/favicon/static_file/sourceable.yml +3 -0
  19. data/config/jekyll/favicon/static_file/taggable.yml +22 -0
  20. data/gemfiles/jekyll36.gemfile +6 -0
  21. data/gemfiles/jekyll37.gemfile +6 -0
  22. data/gemfiles/jekyll38.gemfile +6 -0
  23. data/gemfiles/jekyll39.gemfile +6 -0
  24. data/gemfiles/jekyll40.gemfile +6 -0
  25. data/gemfiles/jekyll41.gemfile +6 -0
  26. data/gemfiles/jekyll42.gemfile +6 -0
  27. data/jekyll-favicon.gemspec +8 -8
  28. data/lib/jekyll-favicon.rb +7 -14
  29. data/lib/jekyll/favicon.rb +19 -13
  30. data/lib/jekyll/favicon/configuration.rb +73 -0
  31. data/lib/jekyll/favicon/configuration/defaults.rb +49 -0
  32. data/lib/jekyll/favicon/generator.rb +11 -84
  33. data/lib/jekyll/favicon/hooks.rb +12 -10
  34. data/lib/jekyll/favicon/static_data_file.rb +17 -0
  35. data/lib/jekyll/favicon/static_file.rb +97 -0
  36. data/lib/jekyll/favicon/static_file/convertible.rb +118 -0
  37. data/lib/jekyll/favicon/static_file/mutable.rb +81 -0
  38. data/lib/jekyll/favicon/static_file/referenceable.rb +22 -0
  39. data/lib/jekyll/favicon/static_file/sourceable.rb +73 -0
  40. data/lib/jekyll/favicon/static_file/taggable.rb +59 -0
  41. data/lib/jekyll/favicon/static_graphic_file.rb +21 -0
  42. data/lib/jekyll/favicon/tag.rb +14 -16
  43. data/lib/jekyll/favicon/utils.rb +24 -0
  44. data/lib/jekyll/favicon/utils/configuration/compact.rb +61 -0
  45. data/lib/jekyll/favicon/utils/configuration/merge.rb +63 -0
  46. data/lib/jekyll/favicon/utils/configuration/patch.rb +48 -0
  47. data/lib/jekyll/favicon/utils/convert.rb +42 -0
  48. data/lib/jekyll/favicon/utils/tag.rb +54 -0
  49. data/lib/jekyll/favicon/version.rb +3 -1
  50. metadata +71 -73
  51. data/.rubocop.yml +0 -5
  52. data/.ruby-version +0 -1
  53. data/.travis.yml +0 -21
  54. data/Gemfile.lock +0 -97
  55. data/lib/browserconfig.rb +0 -54
  56. data/lib/hash.rb +0 -12
  57. data/lib/image.rb +0 -33
  58. data/lib/jekyll/favicon/config/defaults.yml +0 -55
  59. data/lib/jekyll/favicon/icon.rb +0 -73
  60. data/lib/jekyll/favicon/metadata.rb +0 -12
  61. data/lib/jekyll/favicon/templates/chrome.html.erb +0 -6
  62. data/lib/jekyll/favicon/templates/classic.html.erb +0 -8
  63. data/lib/jekyll/favicon/templates/ie.html.erb +0 -4
  64. data/lib/jekyll/favicon/templates/safari.html.erb +0 -8
  65. data/lib/string.rb +0 -14
  66. data/lib/webmanifest.rb +0 -30
@@ -1,14 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'jekyll/hooks'
4
+
1
5
  Jekyll::Hooks.register :site, :after_init do |site|
2
- Jekyll::Favicon.merge site.config['favicon']
3
- favicon_config = Jekyll::Favicon.config
4
- site.config['exclude'] << favicon_config['source']
5
- site.config['exclude'] << favicon_config['chrome']['manifest']['source']
6
- site.config['exclude'] << favicon_config['ie']['browserconfig']['source']
7
- end
6
+ static_files = Jekyll::Favicon.assets(site)
7
+ .uniq(&:path)
8
+ excludes = site.config['exclude']
9
+ static_files.each do |static_file|
10
+ source = static_file.source_relative_path
11
+ excludes << source and next if static_file.generable?
8
12
 
9
- Jekyll::Hooks.register :site, :post_write do |site|
10
- favicon_generators = site.generators.select do |generator|
11
- generator.is_a? Jekyll::Favicon::Generator
13
+ Jekyll.logger.warn Jekyll::Favicon,
14
+ "Missing #{source}, not generating favicons."
12
15
  end
13
- favicon_generators.each(&:clean)
14
16
  end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'jekyll/favicon/static_file'
4
+ require 'jekyll/favicon/static_file/mutable'
5
+
6
+ module Jekyll
7
+ module Favicon
8
+ # StaticFile extension for data exchange formats
9
+ class StaticDataFile < StaticFile
10
+ include StaticFile::Mutable
11
+
12
+ def generable?
13
+ true
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,97 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'pathname'
4
+ require 'forwardable'
5
+ require 'jekyll/static_file'
6
+ require 'jekyll/favicon/static_file/sourceable'
7
+ require 'jekyll/favicon/static_file/taggable'
8
+ require 'jekyll/favicon/static_file/referenceable'
9
+ require 'jekyll/favicon/utils'
10
+ require 'jekyll/favicon/configuration'
11
+
12
+ module Jekyll
13
+ module Favicon
14
+ # Class for static files from with spec dictionary
15
+ # Modify source from spec source
16
+ # Enable tags from spec tags
17
+ # Enable refer
18
+ class StaticFile < Jekyll::StaticFile
19
+ include StaticFile::Sourceable
20
+ include StaticFile::Taggable
21
+ include StaticFile::Referenceable
22
+
23
+ attr_reader :spec, :site
24
+
25
+ def initialize(site, spec = {})
26
+ raise StandardError unless spec.include? 'name'
27
+
28
+ @spec = spec
29
+ spec_dir, spec_name = File.split spec_relative_path
30
+ super site, site.source, spec_dir, spec_name
31
+ end
32
+
33
+ def generable?
34
+ sourceable?
35
+ end
36
+
37
+ def taggable?
38
+ generable? && super
39
+ end
40
+
41
+ def patch(configuration)
42
+ taggable_patch spec_patch configuration
43
+ end
44
+
45
+ def href
46
+ Pathname.new('/')
47
+ .join(url)
48
+ .to_s
49
+ end
50
+
51
+ private
52
+
53
+ def spec_patch(configuration)
54
+ Utils.patch configuration do |value|
55
+ case value
56
+ when :site_dir then site_dir
57
+ when :background then site_background
58
+ when :href then href
59
+ else value
60
+ end
61
+ end
62
+ end
63
+
64
+ def site_dir
65
+ site_configuration.fetch('dir', '.')
66
+ end
67
+
68
+ def site_background
69
+ site_configuration.fetch('background', 'transparent')
70
+ end
71
+
72
+ def site_configuration
73
+ Configuration.merged site
74
+ end
75
+
76
+ def spec_relative_path
77
+ spec_relative_pathname.cleanpath
78
+ end
79
+
80
+ def spec_relative_pathname
81
+ return spec_pathname if spec_pathname.relative?
82
+
83
+ pathname.relative_path_from '/'
84
+ end
85
+
86
+ def spec_pathname
87
+ Pathname.new(site_dir)
88
+ .join(*spec_dir_name)
89
+ end
90
+
91
+ def spec_dir_name
92
+ spec.values_at('dir', 'name')
93
+ .compact
94
+ end
95
+ end
96
+ end
97
+ end
@@ -0,0 +1,118 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'jekyll/favicon/configuration/defaults'
4
+ require 'jekyll/favicon/utils'
5
+
6
+ module Jekyll
7
+ module Favicon
8
+ class StaticFile < Jekyll::StaticFile
9
+ # Create static file based on a source file
10
+ module Convertible
11
+ include Configuration::Defaults
12
+
13
+ def convertible?
14
+ convert.any? || convert_allow_empty?
15
+ end
16
+
17
+ def convert
18
+ convert_defaults = convertible_defaults.dig File.extname(path), @extname
19
+ convert_normalized = convert_normalize convert_spec
20
+ convert_consolidated = Utils.merge convert_defaults, convert_normalized
21
+ patch convert_patch(convert_consolidated || {})
22
+ end
23
+
24
+ def convertible_patch(configuration)
25
+ Utils.patch configuration do |value|
26
+ case value
27
+ when :sizes then sizes.join ' '
28
+ else value
29
+ end
30
+ end
31
+ end
32
+
33
+ def sizes
34
+ if (match = name.match(/^.*-(\d+x\d+)\..*$/)) then [match[1]]
35
+ elsif (define = convert_spec['define'])
36
+ define.split('=').last.split(',').collect { |size| [size, size].join 'x' }
37
+ elsif (resize = convert_spec['resize']) then [resize]
38
+ elsif (scale = convert_spec['scale']) then [scale]
39
+ end
40
+ end
41
+
42
+ # Jekyll::StaticFile method
43
+ # asks if dest mtime is older than source mtime after original modified?
44
+ def modified?
45
+ super || self.class.mtimes[href] < mtime
46
+ end
47
+
48
+ # Jekyll::StaticFile method
49
+ # adds dest mtime to list after original write
50
+ # :reek:ControlParameter
51
+ def write(dest)
52
+ super(dest) && self.class.mtimes[href] = mtime
53
+ end
54
+
55
+ private
56
+
57
+ # Jekyll::StaticFile method
58
+ # add file creation instead of copying
59
+ def copy_file(dest_path)
60
+ case @extname
61
+ when '.svg' then super(dest_path)
62
+ when '.ico', '.png'
63
+ Utils.convert path, dest_path, convert
64
+ else Jekyll.logger.warn "Jekyll::Favicon: Can't generate " \
65
+ " #{dest_path}. Extension not supported."
66
+ end
67
+ end
68
+
69
+ def convert_allow_empty?
70
+ @extname == '.svg' && @extname == File.extname(path)
71
+ end
72
+
73
+ def convert_spec
74
+ spec.fetch 'convert', {}
75
+ end
76
+
77
+ def convert_normalize(options)
78
+ return {} unless options
79
+
80
+ Utils.compact options.slice(*convertible_defaults['defaults'].keys)
81
+ end
82
+
83
+ def convert_defaults
84
+ convertible_defaults.dig File.extname(path), @extname
85
+ end
86
+
87
+ # :reek:FeatureEnvy
88
+ def convert_patch(options)
89
+ %w[density extent].each do |name|
90
+ method = "convert_patch_#{name}".to_sym
91
+ options.merge! name => send(method, options[name])
92
+ end
93
+ Utils.compact options.slice(*convertible_defaults['defaults'].keys)
94
+ end
95
+
96
+ def convert_patch_density(density)
97
+ case density
98
+ when :max
99
+ length = sizes.collect { |size| size.split('x').max }.max.to_i
100
+ length * 3
101
+ else density
102
+ end
103
+ end
104
+
105
+ def convert_patch_extent(extent)
106
+ case extent
107
+ when :auto
108
+ if (size = sizes.first)
109
+ width, height = size.split 'x'
110
+ size if width != height
111
+ end
112
+ else extent
113
+ end
114
+ end
115
+ end
116
+ end
117
+ end
118
+ end
@@ -0,0 +1,81 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rexml/document'
4
+ require 'jekyll/favicon/utils'
5
+ require 'jekyll/favicon/static_graphic_file'
6
+
7
+ module Jekyll
8
+ module Favicon
9
+ class StaticFile < Jekyll::StaticFile
10
+ # Create static file based on a source file
11
+ module Mutable
12
+ def mutable?
13
+ mutation.any? || super
14
+ end
15
+
16
+ def mutation
17
+ refers = case @extname
18
+ when '.xml'
19
+ mutation_refers.select { |refer| refer.key? 'browserconfig' }
20
+ else
21
+ mutation_refers.collect { |refer| refer['webmanifest'] }
22
+ .compact
23
+ end
24
+ patch(Utils.merge(*refers) || {})
25
+ end
26
+
27
+ # overrides Jekyll::StaticFile method
28
+ def mtime
29
+ return super if File.file? path
30
+ end
31
+
32
+ private
33
+
34
+ # overrides Jekyll::StaticFile method
35
+ def copy_file(dest_path)
36
+ # return unless mutable?
37
+ # return super(dest_path) unless mutation.any?
38
+
39
+ File.write dest_path, mutated_content
40
+ end
41
+
42
+ def mutated_content
43
+ case @extname
44
+ when '.json', '.webmanifest', '.manifest' then mutated_content_json
45
+ when '.xml' then mutated_content_xml
46
+ end
47
+ end
48
+
49
+ def mutated_content_json
50
+ mutated = Jekyll::Utils.deep_merge_hashes (mutable || {}), mutation
51
+ JSON.pretty_generate mutated
52
+ end
53
+
54
+ def mutated_content_xml
55
+ mutated = Utils.mutate_element (mutable || REXML::Document.new), mutation
56
+ output = String.new
57
+ mutated.write output
58
+ output
59
+ end
60
+
61
+ def mutable
62
+ return unless File.file? path
63
+
64
+ content = File.read path
65
+ case File.extname path
66
+ when '.xml' then REXML::Document.new content
67
+ else JSON.parse content
68
+ end
69
+ end
70
+
71
+ def mutation_refers
72
+ site.static_files
73
+ .select { |static_file| static_file.is_a? StaticFile }
74
+ .select(&:referenceable?)
75
+ .collect(&:refer)
76
+ .flatten
77
+ end
78
+ end
79
+ end
80
+ end
81
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'jekyll/favicon/configuration/defaults'
4
+
5
+ module Jekyll
6
+ module Favicon
7
+ class StaticFile < Jekyll::StaticFile
8
+ # Add reference to a static file
9
+ module Referenceable
10
+ include Configuration::Defaults
11
+
12
+ def referenceable?
13
+ refer.any?
14
+ end
15
+
16
+ def refer
17
+ patch spec.fetch('refer', [])
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,73 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'jekyll/favicon/configuration/defaults'
4
+ require 'jekyll/favicon/utils'
5
+
6
+ module Jekyll
7
+ module Favicon
8
+ class StaticFile < Jekyll::StaticFile
9
+ # Add source to a static file
10
+ module Sourceable
11
+ include Configuration::Defaults
12
+
13
+ def sourceable?
14
+ source.any? && File.file?(path)
15
+ end
16
+
17
+ def source
18
+ Utils.merge sourceable_defaults, source_site, source_asset
19
+ end
20
+
21
+ # overrides Jekyll::StaticFile method
22
+ def path
23
+ File.join(*[@base, source_relative_path].compact)
24
+ end
25
+
26
+ def source_relative_path
27
+ source_relative_pathname.to_s
28
+ end
29
+
30
+ def self.source_normalize(options)
31
+ case options
32
+ when String
33
+ source_dir, source_name = File.split options
34
+ { 'dir' => source_dir, 'name' => source_name }
35
+ when Hash
36
+ Utils.compact options
37
+ else {}
38
+ end
39
+ end
40
+
41
+ def self.source_filter(options)
42
+ options.fetch 'source', {}
43
+ end
44
+
45
+ private
46
+
47
+ def source_relative_pathname
48
+ Pathname.new(source['dir'])
49
+ .join(source['name'])
50
+ .cleanpath
51
+ end
52
+
53
+ def source_defaults
54
+ sourceable_defaults
55
+ end
56
+
57
+ def source_site
58
+ site_config = Configuration.merged @site
59
+ config = Sourceable.source_filter site_config
60
+ Sourceable.source_normalize config
61
+ end
62
+
63
+ def source_spec
64
+ Sourceable.source_filter spec
65
+ end
66
+
67
+ def source_asset
68
+ Sourceable.source_normalize source_spec
69
+ end
70
+ end
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,59 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rexml/document'
4
+ require 'jekyll/favicon/configuration/defaults'
5
+ require 'jekyll/favicon/utils'
6
+
7
+ module Jekyll
8
+ module Favicon
9
+ class StaticFile < Jekyll::StaticFile
10
+ # Add tags to favicon's static files
11
+ module Taggable
12
+ include Configuration::Defaults
13
+
14
+ def taggable?
15
+ tags.any?
16
+ end
17
+
18
+ def tags
19
+ tag_spec.collect do |options|
20
+ tag_name, tag_options = options.first
21
+ tag_defaults = taggable_defaults[tag_name]
22
+ tag_attributes = tag_defaults.merge tag_options
23
+ tag_build tag_name, patch(tag_attributes)
24
+ end
25
+ end
26
+
27
+ private
28
+
29
+ def tag_spec
30
+ spec.fetch 'tag', []
31
+ end
32
+
33
+ # :reek:UtilityFunction
34
+ def tag_build(name, attributes = {})
35
+ config = attributes.transform_keys { |key| "_#{key}" }
36
+ Jekyll::Favicon::Utils.build_element name, nil, config
37
+ end
38
+
39
+ def mimetype
40
+ mappings = {
41
+ '.ico' => 'image/x-icon',
42
+ '.png' => 'image/png',
43
+ '.svg' => 'image/svg+xml'
44
+ }
45
+ mappings[extname]
46
+ end
47
+
48
+ def taggable_patch(configuration)
49
+ Favicon::Utils.patch configuration do |value|
50
+ case value
51
+ when :mime then mimetype
52
+ else value
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end