distorted-jekyll 0.6.0 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (48) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -1
  3. data/lib/distorted-jekyll.rb +0 -4
  4. data/lib/distorted-jekyll/{template/13th-style.css → 13th-style.css} +0 -0
  5. data/lib/distorted-jekyll/13th-style.rb +1 -1
  6. data/lib/distorted-jekyll/_config_default.yml +3 -21
  7. data/lib/distorted-jekyll/invoker.rb +194 -219
  8. data/lib/distorted-jekyll/liquid_liquid.rb +255 -0
  9. data/lib/distorted-jekyll/liquid_liquid/anchor.liquid +5 -0
  10. data/lib/distorted-jekyll/liquid_liquid/anchor_inline.liquid +1 -0
  11. data/lib/distorted-jekyll/liquid_liquid/embed.liquid +1 -0
  12. data/lib/distorted-jekyll/liquid_liquid/img.liquid +1 -0
  13. data/lib/distorted-jekyll/liquid_liquid/object.liquid +5 -0
  14. data/lib/distorted-jekyll/liquid_liquid/picture.liquid +15 -0
  15. data/lib/distorted-jekyll/liquid_liquid/picture.rb +48 -0
  16. data/lib/distorted-jekyll/liquid_liquid/picture_source.liquid +1 -0
  17. data/lib/distorted-jekyll/liquid_liquid/root.liquid +5 -0
  18. data/lib/distorted-jekyll/liquid_liquid/video.liquid +5 -0
  19. data/lib/distorted-jekyll/liquid_liquid/video_source.liquid +1 -0
  20. data/lib/distorted-jekyll/md_injection.rb +30 -25
  21. data/lib/distorted-jekyll/media_molecule.rb +20 -0
  22. data/lib/distorted-jekyll/media_molecule/font.rb +21 -0
  23. data/lib/distorted-jekyll/media_molecule/image.rb +15 -0
  24. data/lib/distorted-jekyll/media_molecule/never_let_you_down.rb +28 -0
  25. data/lib/distorted-jekyll/media_molecule/pdf.rb +108 -0
  26. data/lib/distorted-jekyll/media_molecule/svg.rb +20 -0
  27. data/lib/distorted-jekyll/media_molecule/text.rb +23 -0
  28. data/lib/distorted-jekyll/media_molecule/video.rb +45 -0
  29. data/lib/distorted-jekyll/monkey_business/jekyll/cleaner.rb +68 -1
  30. data/lib/distorted-jekyll/static_state.rb +19 -60
  31. data/lib/distorted-jekyll/the_setting_sun.rb +179 -0
  32. metadata +26 -21
  33. data/lib/distorted-jekyll/floor.rb +0 -266
  34. data/lib/distorted-jekyll/molecule/font.rb +0 -62
  35. data/lib/distorted-jekyll/molecule/image.rb +0 -94
  36. data/lib/distorted-jekyll/molecule/lastresort.rb +0 -51
  37. data/lib/distorted-jekyll/molecule/pdf.rb +0 -79
  38. data/lib/distorted-jekyll/molecule/svg.rb +0 -47
  39. data/lib/distorted-jekyll/molecule/text.rb +0 -62
  40. data/lib/distorted-jekyll/molecule/video.rb +0 -85
  41. data/lib/distorted-jekyll/template/error_code.liquid +0 -3
  42. data/lib/distorted-jekyll/template/font.liquid +0 -32
  43. data/lib/distorted-jekyll/template/image.liquid +0 -32
  44. data/lib/distorted-jekyll/template/lastresort.liquid +0 -20
  45. data/lib/distorted-jekyll/template/pdf.liquid +0 -14
  46. data/lib/distorted-jekyll/template/svg.liquid +0 -32
  47. data/lib/distorted-jekyll/template/text.liquid +0 -32
  48. data/lib/distorted-jekyll/template/video.liquid +0 -11
@@ -0,0 +1,179 @@
1
+ require 'yaml'
2
+ require 'jekyll'
3
+ require 'set'
4
+
5
+ require 'distorted/monkey_business/hash'
6
+ require 'distorted/checking_you_out'
7
+
8
+
9
+ module Jekyll; end
10
+ module Jekyll::DistorteD
11
+
12
+ # Top-level config key (once stringified) for Jekyll and Default YAML.
13
+ CONFIG_ROOT_KEY = :distorted
14
+
15
+ # Filename for default config YAML. Should be a sibling of this file.
16
+ # Don't move this file or the YAML defaults without changing this.
17
+ DEFAULT_CONFIG_FILE_NAME = '_config_default.yml'.freeze
18
+ DEFAULT_CONFIG_PATH = File.join(File.dirname(__FILE__), DEFAULT_CONFIG_FILE_NAME).freeze
19
+
20
+ # Separator character for pretty-printing config hierarchy.
21
+ PP_SEPARATOR = "\u2B9E ".encode('utf-8').freeze
22
+
23
+ # Path separator is almost always '/' internally, but support
24
+ # ALT_SEPARATOR platforms too.
25
+ # On Lunix - Ruby 2.7:
26
+ # irb(main):003:0> File::ALT_SEPARATOR
27
+ # => nil
28
+ # irb(main):004:0> File::SEPARATOR
29
+ # => "/"
30
+ PATH_SEPARATOR = (File::ALT_SEPARATOR || File::SEPARATOR).freeze
31
+
32
+ # Any any attr value will get a to_sym if shorter than this
33
+ # totally arbitrary length, or if the attr key is in the plugged
34
+ # Molecule's set of attrs that take only a defined set of values.
35
+ # My chosen boundary length fits all of the outer-limit tag names I use,
36
+ # like 'medium'. It fits the longest value of Vips::Interesting too,
37
+ # though `crop` will be symbolized based on the other condition.
38
+ ARBITRARY_ATTR_SYMBOL_STRING_LENGTH_BOUNDARY = 13
39
+
40
+
41
+ # Memoization Hash for all settings data so we don't have to reprocess it for additional lookups.
42
+ def self.memories
43
+ @@memories ||= Hash.new
44
+ end
45
+
46
+ # Memoize the complete default-config to avoid touching the filesystem more than once.
47
+ def self.distorted_default_settings
48
+ @@distorted_default_settings ||= YAML.load(File.read(DEFAULT_CONFIG_PATH))
49
+ end
50
+
51
+ # Stores a given settings path/value to our memoization Hash
52
+ # after normalizing the values, so we can be less strict about
53
+ # the YAML formats we accept because YAML is easy to mess up.
54
+ def self.memories!(key_paths, sources)
55
+ # Avoid redundant memory transformations for keys we already have.
56
+ # NOTE: This assumes settings will never change over the execution lifetime
57
+ # of any single DistorteD instance.
58
+ return self.memories.dig(key_paths) if self.memories.has_key?(key_paths)
59
+ # Shorten long path members (any with underscores) so long log lines
60
+ # don't get misaligned easily.
61
+ # Don't log glob paths — those containing as asterisk (*).
62
+ log_key = key_paths.detect { |path| path.none?(:"*") }.map(&:to_s).map{ |component|
63
+ component.include?('_'.freeze) ? component.split('_'.freeze).map(&:chr).join('_'.freeze) : component
64
+ }.join(PP_SEPARATOR.to_s).freeze
65
+
66
+ # Try one one source Proc at a time, looking for every settings-path within it.
67
+ # If *any* config data is returned from a source we stop processing additional sources.
68
+ # This is to allow for default-config overriding because otherwise if we always
69
+ # use the default config it would be impossible to turn off any of that data.
70
+ memory = sources.reduce(nil) { |out, source|
71
+ key_paths.each { |key_path|
72
+ case new = source.call(key_path)
73
+ when [out, new].all? { |c| c&.respond_to?(:update) } then out.update(new)
74
+ when [out, new].all? { |c| c&.respond_to?(:merge) } then out.merge(new)
75
+ when [out, new].all? { |c| c&.respond_to?(:concat) } then out.concat(new)
76
+ else out = new
77
+ end
78
+ }
79
+ Jekyll.logger.debug(log_key, out) unless out.nil?
80
+ break out unless out.nil?
81
+ }
82
+
83
+ # Most of our settings data comes from a YAML source,
84
+ # either Jekyll's config or our Gem's built-in defaults,
85
+ # so we should do some normalization before memoizing.
86
+ memory = case memory
87
+ when Array
88
+ # Transform Array members, then transform the Array itself to a Set to dedupe.
89
+ memory.map{ |array_member|
90
+ case array_member
91
+ # Symbolize Hash keys as well as String values if it has any.
92
+ when Hash then array_member.transform_keys!(&:to_sym).transform_values!{ |hash_value|
93
+ case hash_value
94
+ when String then (hash_value.length <= ARBITRARY_ATTR_SYMBOL_STRING_LENGTH_BOUNDARY) ? hash_value.to_sym : hash_value
95
+ else hash_value
96
+ end
97
+ }
98
+ # For sub-Arrays of our Array, Symbolize their keys
99
+ when Array then array_member.map(&:to_sym)
100
+ # Otherwise just pass it as it was loaded from YAML
101
+ else array_member
102
+ end
103
+ }.to_set
104
+ when Hash
105
+ # Ruby::YAML::load will parse YAML Sets (the `?` list-like syntax)
106
+ # as a Ruby Hash with all-nil values (the internal implementation of Set)
107
+ # unless we give our YAML files some sugar telling it what class we want:
108
+ # https://rhnh.net/2011/01/31/yaml-tutorial/
109
+ #
110
+ # I wouldn't mind maintaining the default-settings YAML file with those tags,
111
+ # but that would make it really tedious and error-prone in the Jekyll config
112
+ # if/when it comes time to override any defaults, so I em ignoring that capability
113
+ # and doing my own normalization here in this method.
114
+ memory.values.all?{|v| v.nil?} ? memory.keys.map(&:to_sym).to_set : memory.transform_keys(&:to_sym)
115
+ else memory
116
+ end
117
+ # Use the `key_paths` Array[Array[String] as the Hash key directly to avoid the complexity
118
+ # of trying to splat it and nest the keys in layers of other Hashes.
119
+ self.memories.store(key_paths, memory)
120
+ end
121
+
122
+ # Generic main config-loading function that will search, in order:
123
+ # - The memoized pre-transformed config data store in-memory.
124
+ # - Jekyll's Site config, for a passed-in site or for the default site.
125
+ # - DistorteD's Gem-internal default config YAML.
126
+ #
127
+ # Optionally provide a class to be used as a fallback for missing keys.
128
+ def self.the_setting_sun(*keys, site: Jekyll.sites.first, **kw)
129
+ return nil if keys.empty?
130
+
131
+ # Normalize given keys into an Array[Array[<whatever>] given these rules:
132
+ #
133
+ # - If all of our given keys are Arrays, assume each Array is a separate settings-path
134
+ # and leave them alone, e.g. [['jekyll', 'destination']] would be passed unchanged.
135
+ #
136
+ # - If some of our given keys are Arrays and some are not, assume the Arrays are incomplete
137
+ # settings-paths (suffixes) and assume the non-Arrays are prefixes that should be applied
138
+ # to each suffix, e.g.
139
+ # ['changes', ['image', '*'], ['image', 'jpeg']] becomes [['changes', 'image', 'jpeg'], ['changes', 'image', '*']]
140
+ #
141
+ # - If none of our given keys are an Array, assume the given keys make up
142
+ # a single settings-path and wrap them in an Array, e.g.:
143
+ # ['jekyll', 'destination'] becomes [['jekyll', 'destination']]
144
+ key_paths = case
145
+ when keys.all?(Array) then keys
146
+ when keys.any?(Array) then
147
+ keys.map.partition(&Array.method(:===)).yield_self.with_object(Array.new) { |(suffixes, prefix), combined_paths|
148
+ suffixes.each{ |suffix| combined_paths.push(suffix.unshift(*prefix)) }
149
+ }
150
+ when keys.none?(Array) then Array[keys]
151
+ end.map { |key_path|
152
+ # Now inspect the first key of each combined path and transform accordingly:
153
+ # - Opposite Day — :jekyll-prefixed paths get the prefix removed
154
+ # because that key level doesn't exist in the Jekyll config.
155
+ # - If it already has out prefix, leave it alone.
156
+ # - Everything else gets our :distorted prefix added if missing
157
+ # so I don't have to refer to the constant externally.
158
+ # Finally, Symbolize errething for Hash key consistency in memoization
159
+ # even though some config getters will map them back to Strings.
160
+ case key_path.first.to_sym
161
+ when :jekyll, :Jekyll then key_path.drop(1)
162
+ when CONFIG_ROOT_KEY then key_path.map(&:to_sym)
163
+ else key_path.unshift(CONFIG_ROOT_KEY).map(&:to_sym)
164
+ end
165
+ }
166
+
167
+ # Do The Thing
168
+ return memories!(key_paths, Array[
169
+ ->(key_path){ site.config.dig(*key_path.map(&:to_s))},
170
+ ->(key_path){ self::distorted_default_settings.dig(*key_path.map(&:to_s))},
171
+ ])
172
+ end # self.the_setting_sun
173
+ end # module Jekyll::DistorteD
174
+
175
+
176
+ module Jekyll::DistorteD::Setting
177
+ # Instance version of Setting entry-point.
178
+ def the_setting_sun(*a, **k, &b); Jekyll::DistorteD::the_setting_sun(*a, **k, &b); end
179
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: distorted-jekyll
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.0
4
+ version: 0.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - okeeblow
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-10-19 00:00:00.000000000 Z
11
+ date: 2021-01-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -86,14 +86,14 @@ dependencies:
86
86
  requirements:
87
87
  - - "~>"
88
88
  - !ruby/object:Gem::Version
89
- version: 0.6.0
89
+ version: 0.7.0
90
90
  type: :runtime
91
91
  prerelease: false
92
92
  version_requirements: !ruby/object:Gem::Requirement
93
93
  requirements:
94
94
  - - "~>"
95
95
  - !ruby/object:Gem::Version
96
- version: 0.6.0
96
+ version: 0.7.0
97
97
  - !ruby/object:Gem::Dependency
98
98
  name: kramdown
99
99
  requirement: !ruby/object:Gem::Requirement
@@ -119,30 +119,35 @@ files:
119
119
  - LICENSE
120
120
  - README.md
121
121
  - lib/distorted-jekyll.rb
122
+ - lib/distorted-jekyll/13th-style.css
122
123
  - lib/distorted-jekyll/13th-style.rb
123
124
  - lib/distorted-jekyll/_config_default.yml
124
125
  - lib/distorted-jekyll/blocks.rb
125
- - lib/distorted-jekyll/floor.rb
126
126
  - lib/distorted-jekyll/invoker.rb
127
+ - lib/distorted-jekyll/liquid_liquid.rb
128
+ - lib/distorted-jekyll/liquid_liquid/anchor.liquid
129
+ - lib/distorted-jekyll/liquid_liquid/anchor_inline.liquid
130
+ - lib/distorted-jekyll/liquid_liquid/embed.liquid
131
+ - lib/distorted-jekyll/liquid_liquid/img.liquid
132
+ - lib/distorted-jekyll/liquid_liquid/object.liquid
133
+ - lib/distorted-jekyll/liquid_liquid/picture.liquid
134
+ - lib/distorted-jekyll/liquid_liquid/picture.rb
135
+ - lib/distorted-jekyll/liquid_liquid/picture_source.liquid
136
+ - lib/distorted-jekyll/liquid_liquid/root.liquid
137
+ - lib/distorted-jekyll/liquid_liquid/video.liquid
138
+ - lib/distorted-jekyll/liquid_liquid/video_source.liquid
127
139
  - lib/distorted-jekyll/md_injection.rb
128
- - lib/distorted-jekyll/molecule/font.rb
129
- - lib/distorted-jekyll/molecule/image.rb
130
- - lib/distorted-jekyll/molecule/lastresort.rb
131
- - lib/distorted-jekyll/molecule/pdf.rb
132
- - lib/distorted-jekyll/molecule/svg.rb
133
- - lib/distorted-jekyll/molecule/text.rb
134
- - lib/distorted-jekyll/molecule/video.rb
140
+ - lib/distorted-jekyll/media_molecule.rb
141
+ - lib/distorted-jekyll/media_molecule/font.rb
142
+ - lib/distorted-jekyll/media_molecule/image.rb
143
+ - lib/distorted-jekyll/media_molecule/never_let_you_down.rb
144
+ - lib/distorted-jekyll/media_molecule/pdf.rb
145
+ - lib/distorted-jekyll/media_molecule/svg.rb
146
+ - lib/distorted-jekyll/media_molecule/text.rb
147
+ - lib/distorted-jekyll/media_molecule/video.rb
135
148
  - lib/distorted-jekyll/monkey_business/jekyll/cleaner.rb
136
149
  - lib/distorted-jekyll/static_state.rb
137
- - lib/distorted-jekyll/template/13th-style.css
138
- - lib/distorted-jekyll/template/error_code.liquid
139
- - lib/distorted-jekyll/template/font.liquid
140
- - lib/distorted-jekyll/template/image.liquid
141
- - lib/distorted-jekyll/template/lastresort.liquid
142
- - lib/distorted-jekyll/template/pdf.liquid
143
- - lib/distorted-jekyll/template/svg.liquid
144
- - lib/distorted-jekyll/template/text.liquid
145
- - lib/distorted-jekyll/template/video.liquid
150
+ - lib/distorted-jekyll/the_setting_sun.rb
146
151
  homepage: https://cooltrainer.org
147
152
  licenses:
148
153
  - AGPL-3.0
@@ -1,266 +0,0 @@
1
- require 'yaml'
2
- require 'jekyll'
3
- require 'set'
4
-
5
- require 'distorted/monkey_business/hash'
6
- require 'distorted/checking_you_out'
7
-
8
-
9
- module Jekyll
10
- module DistorteD
11
- module Floor
12
-
13
- ATTRIBUTES = Set[:lower_world, :changes, :outer_limits]
14
-
15
- # Top-level config key (once stringified) for Jekyll and Default YAML.
16
- CONFIG_ROOT = :distorted
17
-
18
- # Filename for default config YAML. Should be a sibling of this file.
19
- # Don't move this file or the YAML defaults without changing this.
20
- DEFAULT_CONFIG_FILE_NAME = '_config_default.yml'.freeze
21
- DEFAULT_CONFIG_PATH = File.join(File.dirname(__FILE__), DEFAULT_CONFIG_FILE_NAME).freeze
22
-
23
- # Separator character for pretty-printing config hierarchy.
24
- PP_SEPARATOR = "\u21e2 ".encode('utf-8').freeze
25
-
26
- # Path separator is almost always '/' internally, but support
27
- # ALT_SEPARATOR platforms too.
28
- # On Lunix - Ruby 2.7:
29
- # irb(main):003:0> File::ALT_SEPARATOR
30
- # => nil
31
- # irb(main):004:0> File::SEPARATOR
32
- # => "/"
33
- PATH_SEPARATOR = (File::ALT_SEPARATOR || File::SEPARATOR).freeze
34
-
35
-
36
- # Generic main config-loading function that will search, in order:
37
- # - The memoized pre-transformed config data store in-memory.
38
- # - Jekyll's Site config, for a passed-in site or for the default site.
39
- # - DistorteD's Gem-internal default config YAML.
40
- #
41
- # Optionally provide a class to be used as a fallback for missing keys.
42
- def self.config(*keys, **kw)
43
- # Symbolize for our internal representation of the config path.
44
- # The Jekyll config and default config are both YAML, so we want string
45
- # keys for them. Go ahead and prepend the top-level search key here too.
46
- memo_keys = keys.compact.map(&:to_sym).to_set
47
- search_keys = keys.compact.map(&:to_s).map(&:freeze)
48
- # Pretty print the config path for logging.
49
- log_key = search_keys.join(PP_SEPARATOR.to_s).freeze
50
- # Initialize memoization class variable as a Hash that will return nil
51
- # for any key access that doesn't already contain something.
52
- @@memories ||= Hash.new { |h,k| h[k] = h.class.new(&h.default_proc) }
53
- # Try to load a memoized config if we can, to skip any filesystem
54
- # access and data transformation steps.
55
- config = @@memories&.dig(*memo_keys)
56
- unless config.nil?
57
- if config.is_a?(TrueClass) || config.is_a?(FalseClass)
58
- return config
59
- elsif config.is_a?(Enumerable)
60
- unless config.empty?
61
- # Can't check this at the top level because True/FalseClass
62
- # don't respond to this message.
63
- return config
64
- end
65
- end
66
- end
67
-
68
- # The key isn't memoized. Look for it first in Jekyll's Site config.
69
- # Is it even possible to have more than one Site? Support being passed
70
- # a `site` object just in case, but taking the first one should be fine.
71
- site = kw[:site] || Jekyll.sites.first
72
- # Get the config, or nil if the queried config path doesn't exist.
73
- loaded_config = site.config.dig(*search_keys)
74
- if loaded_config.nil?
75
- # The wanted config key didn't exist in the Site config, so let's
76
- # try our defaults!
77
- # This file will always be small enough for a one-shot read.
78
- default_config = YAML.load(File.read(DEFAULT_CONFIG_PATH))
79
- loaded_config = default_config.dig(*search_keys)
80
- unless loaded_config.nil?
81
- Jekyll.logger.debug(['Default', log_key].join(PP_SEPARATOR.to_s).concat(':'.freeze), loaded_config)
82
- end
83
- else # else Jekyll _config is not nil
84
- Jekyll.logger.debug(['_config', log_key].join(PP_SEPARATOR.to_s).concat(':'.freeze), loaded_config)
85
- end
86
- # Was the desired config key found in the Gem defaults?
87
- if loaded_config.nil?
88
- # Nope.
89
- return nil
90
- else
91
- # Symbolize any output keys and values, and convert Arrays and Ruby::YAML
92
- # Sets-as-Hashes to Ruby stdlib Sets.
93
- # Returning a Set instead of an Array should be fine since none of our
94
- # configs can (read: should) contain duplicate values for any reason.
95
- loaded_config = symbolic(set_me_free(loaded_config))
96
- end
97
- # Memoize any of our own config, but just return anything outside our tree.
98
- if keys.first == CONFIG_ROOT
99
- @@memories.bury(*memo_keys, loaded_config)
100
- Jekyll.logger.debug(log_key, "Memoizing config: #{@@memories.dig(*memo_keys)}")
101
- # And return a config to the caller. Don't return the `new`ly fetched
102
- # data directly to ensure consistency between this first fetch and
103
- # subsequent memoized fetches, and to let callers take advantage of
104
- # the memo Hash's `default_proc` setup.
105
- return @@memories.dig(*memo_keys)
106
- else
107
- return loaded_config
108
- end
109
- end
110
-
111
- # AFAICT Ruby::YAML will not give me a Ruby Set[] for a YAML Set,
112
- # just a Hash with all-nil-values which is what it is internally.
113
- # distorted⇢ image Trying Jekyll _config key: {"(max-width: 400px)"=>nil, "(min-width: 800px)"=>nil, "(min-width: 1500px)"=>nil}
114
- # It is possible with some sugar in the YAML files, but I don't
115
- # want to ask anyone to do that :)
116
- # https://rhnh.net/2011/01/31/yaml-tutorial/
117
- def self.set_me_free(dunno)
118
- if dunno.class == Array
119
- return dunno&.to_set.map{|d| set_me_free(d)}
120
- elsif dunno.class == Hash
121
- if dunno&.values.all?{|v| v.nil?}
122
- return dunno&.keys.to_set
123
- else
124
- return dunno&.transform_values!{|v| set_me_free(v)}
125
- end
126
- end
127
- return dunno
128
- end
129
-
130
- # Transform arbitrary configuration data structure keys from
131
- # strings to symbols before memoization.
132
- # https://stackoverflow.com/a/8189435
133
- def self.symbolic(dunno)
134
- # Check message-handling responses to gauge emptiness since classes that
135
- # don't respond to `:empty?` might not respond to `:method_exists?` either.
136
- if dunno.nil?
137
- return dunno
138
- elsif dunno.class == Hash
139
- return dunno.transform_keys!(&:to_sym).transform_values!{|v| symbolic(v)}
140
- elsif dunno.class == Array
141
- return dunno.map{|r| symbolic(r)}
142
- elsif dunno.respond_to?(:to_sym)
143
- # Plain types
144
- return dunno.to_sym
145
- elsif dunno.respond_to?(:to_str)
146
- # Freeze string config values.
147
- # Specifically :to_str, not :to_s. Usually implemented by actual Strings.
148
- return dunno.to_str.freeze
149
- end
150
- return dunno
151
- end
152
-
153
- # Returns a Set of Arrays of search keys to try in config()
154
- def search_keys(*keys)
155
- # It's likely that we will get a default argument of [nil]
156
- # here due to the output of abstract(:whatever) for unset attrs.
157
- keys = keys.compact
158
- # If a search key path was given, construct one based
159
- # on the MIME::Type union Set between the source media
160
- # and the plugged MediaMolecule.
161
- if keys.empty? or keys.all?{|k| k.nil?}
162
- try_keys = type_mars.map{ |t|
163
- # Use only the first part of complex sub_types like 'svg+xml'
164
- [t.media_type, t.sub_type.split('+').first].compact
165
- }
166
- else
167
- # Or use a user-provided config path.
168
- try_keys = Set[keys]
169
- end
170
- end
171
-
172
- # Loads configuration data telling us how to open certain
173
- # types of files.
174
- def lower_world(*keys)
175
- # Try each set of keys until we find a match
176
- for try in search_keys(*keys)
177
- tried = Jekyll::DistorteD::Floor::config(
178
- Jekyll::DistorteD::Floor::CONFIG_ROOT,
179
- :welcome,
180
- *try,
181
- )
182
- # Is the YAML config of the appropriate structure?
183
- if tried.is_a?(Hash)
184
- # Non-Hashes may not respond to `empty?`
185
- unless tried.empty?
186
- return tried
187
- end
188
- end
189
- end
190
- end
191
-
192
- # Load configuration telling us what media-types to generate
193
- # for any given media-type input.
194
- def changes(*keys)
195
- out = Set[]
196
- # `changes` media-type[sub_type] config will contain information about
197
- # what variations output format are desired for what input format,
198
- # e.g. {:image => {:jpeg => Set['image/jpeg', 'image/webp']}}
199
- # It is not automatically implied that the source format is also
200
- # an output format!
201
- for try in search_keys(*keys)
202
- tried = Jekyll::DistorteD::Floor::config(
203
- Jekyll::DistorteD::Floor::CONFIG_ROOT,
204
- :changes,
205
- *try,
206
- )
207
- if tried.is_a?(Enumerable) and tried.all?{|t| t.is_a?(String)} and not tried.empty?
208
- tried.each{ |t|
209
- # MIME::Type.new() won't give us a usable Type object:
210
- #
211
- # irb> MIME::Types['image/svg+xml'].first.preferred_extension
212
- # => "svg"
213
- # irb> MIME::Type.new('image/svg+xml').preferred_extension
214
- # => nil
215
- out.merge(CHECKING::YOU::IN(t))
216
- }
217
- end
218
- end
219
-
220
- # If the config didn't give us any MIME::Type changes
221
- # then we will just output the same type we loaded.
222
- if out.empty?
223
- return type_mars
224
- else
225
- return out
226
- end
227
- end
228
-
229
- # Loads configuration telling us what variations to generate for any
230
- # given type of file, or for an arbitrary key hierarchy.
231
- def outer_limits(*keys)
232
- out = Set[]
233
- # See if any config data exists for each given key hierarchy,
234
- # but under the root DistorteD config key.
235
- for try in search_keys(*keys)
236
- tried = Jekyll::DistorteD::Floor::config(
237
- Jekyll::DistorteD::Floor::CONFIG_ROOT,
238
- :outer_limits,
239
- *try,
240
- )
241
-
242
- # Is the YAML config of the appropriate structure?
243
- # Merge a shallow copy of it with the Liquid-given attrs.
244
- # If we don't take a copy the attrs will be memoized into the config.
245
- if tried.is_a?(Enumerable) and tried.all?{|t| t.is_a?(Hash)} and not tried.empty?
246
- out.merge(tried.dup.map{ |d| d.merge(@liquid_liquid) })
247
- end
248
- end
249
-
250
- # We should output something if the config didn't give us anything.
251
- # This is kind of a mess right now with redundancies in the call sites
252
- # of things like Molecule::Image. I'll come up with a better general-
253
- # purpose fallback solution at some point, but for now this will get
254
- # non-Image StaticFiles working with no config :)
255
- if out.empty?
256
- out << {
257
- :tag => :full,
258
- }
259
- end
260
-
261
- return out
262
- end
263
-
264
- end
265
- end
266
- end