distorted-jekyll 0.5.7 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f1dd519e4d15964873a6184c4f47eebb52d8c58b3ac74707095278cce0cfe51d
4
- data.tar.gz: aed8d0eaa3e7d7e18c459add39e6a9136bda7d1408886f4fe514db61f4d77906
3
+ metadata.gz: 5eaf5c713e61dd6cea6fee1d1cb031b7ec25331e8cdeb9aa79f1ea96c61d94a8
4
+ data.tar.gz: '068625124864b575107596d9b91761171eecdb76cdaf8f34a66fa37f4d34b69e'
5
5
  SHA512:
6
- metadata.gz: 510a70a86a7fa6e89880fd6385fb2780e04e2b1a0bd21b2b361eb44fdafa3c05da879802ea8d54d49741cc7a691f877c37491e5774ecd106d0acc86e780d1cab
7
- data.tar.gz: '0174925db366f825a2b5fa6d54b9f26bae4b783315bb82f81762cda503376b25ee8718618df688840ef0f1b237bfc4b196b921af9569d50a472fd6012863473a'
6
+ metadata.gz: 4b55e4771aadea12c70adf95995432b4cff70cf0548b06ae76dcb8a55f11de273531a3f2def6be56de9b7043a9f752a6f7d7cc1f66299475409ac269be80dc77
7
+ data.tar.gz: 4c152988ef67bd5717429578de241169b13f7ffee38cb255979184e2b3cdf4d551d1b50d9c4472ca98bbb9695d8892f09b0b2d9d0e2a02deeeb1dd54d8415f66
@@ -1,6 +1,6 @@
1
1
  require 'distorted-jekyll/13th-style'
2
2
  require 'distorted-jekyll/blocks'
3
- require 'distorted-jekyll/injection_of_love'
3
+ require 'distorted-jekyll/md_injection'
4
4
  require 'distorted-jekyll/invoker'
5
5
 
6
6
 
@@ -21,9 +21,6 @@ standard_image: &standard_image
21
21
  height: 1500
22
22
  media: "(min-width: 800px)"
23
23
 
24
- standard_text: &standard_text
25
- ? image/png
26
- ? image/webp
27
24
 
28
25
  distorted:
29
26
 
@@ -63,10 +60,17 @@ distorted:
63
60
  ? image/png
64
61
  ? image/webp
65
62
  text:
66
- plain: *standard_text
67
- x-nfo: *standard_text
63
+ plain:
64
+ ? text/plain
65
+ ? image/png
66
+ ? image/webp
67
+ x-nfo:
68
+ ? text/x-nfo
69
+ ? image/png
70
+ ? image/webp
68
71
  font:
69
72
  ttf:
73
+ ? font/ttf
70
74
  ? image/png
71
75
  ? image/webp
72
76
 
@@ -75,5 +79,3 @@ distorted:
75
79
  jpeg: *standard_image
76
80
  png: *standard_image
77
81
  webp: *standard_image
78
- font:
79
- ttf: *standard_image
@@ -1,12 +1,16 @@
1
- require 'distorted/monkey_business/hash'
2
1
  require 'yaml'
3
2
  require 'jekyll'
4
3
  require 'set'
5
4
 
5
+ require 'distorted/monkey_business/hash'
6
+ require 'distorted/checking_you_out'
7
+
6
8
 
7
9
  module Jekyll
8
10
  module DistorteD
9
- class Floor
11
+ module Floor
12
+
13
+ ATTRIBUTES = Set[:lower_world, :changes, :outer_limits]
10
14
 
11
15
  # Top-level config key (once stringified) for Jekyll and Default YAML.
12
16
  CONFIG_ROOT = :distorted
@@ -67,14 +71,17 @@ module Jekyll
67
71
  site = kw[:site] || Jekyll.sites.first
68
72
  # Get the config, or nil if the queried config path doesn't exist.
69
73
  loaded_config = site.config.dig(*search_keys)
70
- Jekyll.logger.debug(['_config', log_key].join(PP_SEPARATOR.to_s).concat(':'.freeze), loaded_config || 'No data'.freeze)
71
74
  if loaded_config.nil?
72
75
  # The wanted config key didn't exist in the Site config, so let's
73
76
  # try our defaults!
74
77
  # This file will always be small enough for a one-shot read.
75
78
  default_config = YAML.load(File.read(DEFAULT_CONFIG_PATH))
76
79
  loaded_config = default_config.dig(*search_keys)
77
- Jekyll.logger.debug(['Default', log_key].join(PP_SEPARATOR.to_s).concat(':'.freeze), loaded_config || 'No data'.freeze)
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)
78
85
  end
79
86
  # Was the desired config key found in the Gem defaults?
80
87
  if loaded_config.nil?
@@ -143,6 +150,117 @@ module Jekyll
143
150
  return dunno
144
151
  end
145
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
+
146
264
  end
147
265
  end
148
266
  end
@@ -1,11 +1,12 @@
1
1
  # Our custom Exceptions
2
- require 'distorted-jekyll/error_code'
2
+ require 'distorted/error_code'
3
+
4
+ # MIME::Typer
5
+ require 'distorted/checking_you_out'
3
6
 
4
7
  # Configuration-loading code
5
8
  require 'distorted-jekyll/floor'
6
-
7
- # Configuration data manipulations
8
- require 'distorted-jekyll/molecule/abstract'
9
+ require 'distorted-jekyll/static_state'
9
10
 
10
11
  # Media-type drivers
11
12
  require 'distorted-jekyll/molecule/font'
@@ -14,7 +15,7 @@ require 'distorted-jekyll/molecule/text'
14
15
  require 'distorted-jekyll/molecule/pdf'
15
16
  require 'distorted-jekyll/molecule/svg'
16
17
  require 'distorted-jekyll/molecule/video'
17
- require 'distorted-jekyll/molecule/last-resort'
18
+ require 'distorted-jekyll/molecule/lastresort'
18
19
 
19
20
  # Set.to_hash
20
21
  require 'distorted/monkey_business/set'
@@ -29,10 +30,6 @@ require 'shellwords'
29
30
  # Set is in stdlib but is not in core.
30
31
  require 'set'
31
32
 
32
- # MIME Magic 🧙‍♀️
33
- require 'mime/types'
34
- require 'ruby-filemagic'
35
-
36
33
  # I mean, this is why we're here, right?
37
34
  require 'jekyll'
38
35
 
@@ -44,7 +41,8 @@ module Jekyll
44
41
  GEM_ROOT = File.dirname(__FILE__).freeze
45
42
 
46
43
  # Mix in config-loading methods.
47
- include Jekyll::DistorteD::Molecule::Abstract
44
+ include Jekyll::DistorteD::Floor
45
+ include Jekyll::DistorteD::StaticState
48
46
 
49
47
  # Enabled media_type drivers. These will be attempted back to front.
50
48
  # TODO: Make this configurable.
@@ -57,6 +55,17 @@ module Jekyll
57
55
  Jekyll::DistorteD::Molecule::Video,
58
56
  Jekyll::DistorteD::Molecule::Image,
59
57
  ]
58
+ # Reduce the above to a Hash of Sets of MediaMolecules-per-Type, keyed by Type.
59
+ TYPE_MOLECULES = MEDIA_MOLECULES.reduce(
60
+ Hash.new{|hash, key| hash[key] = Set[]}
61
+ ) { |types, molecule|
62
+ if molecule.const_defined?(:LOWER_WORLD)
63
+ molecule.const_get(:LOWER_WORLD).each { |t|
64
+ types.update(t => Set[molecule]) { |k,o,n| o.merge(n) }
65
+ }
66
+ end
67
+ types
68
+ }
60
69
 
61
70
  # Any any attr value will get a to_sym if shorter than this
62
71
  # totally arbitrary length, or if the attr key is in the plugged
@@ -80,10 +89,21 @@ module Jekyll
80
89
  # Filename is the only non-keyword argument our tag should ever get.
81
90
  # It's spe-shul and gets its own definition outside the attr loop.
82
91
  if parsed_arguments.key?(:src)
83
- @name = parsed_arguments[:src]
92
+ @name = parsed_arguments.delete(:src)
84
93
  else
85
- @name = parsed_arguments[:argv1]
94
+ @name = parsed_arguments.delete(:argv1)
86
95
  end
96
+ @liquid_liquid = parsed_arguments.select{ |attr, val|
97
+ not [nil, ''.freeze].include?(val)
98
+ }.transform_keys { |attr|
99
+ attr.length <= ARBITRARY_ATTR_SYMBOL_STRING_LENGTH_BOUNDARY ? attr.to_sym : attr.freeze
100
+ }.transform_values { |val|
101
+ if val.respond_to?(:length)
102
+ val.length <= ARBITRARY_ATTR_SYMBOL_STRING_LENGTH_BOUNDARY ? val.to_sym : val.freeze
103
+ else
104
+ val
105
+ end
106
+ }
87
107
 
88
108
  # If we didn't get one of the two above options there is nothing we
89
109
  # can do but bail.
@@ -91,173 +111,46 @@ module Jekyll
91
111
  raise "Failed to get a usable filename from #{arguments}"
92
112
  end
93
113
 
94
- # Guess MIME Magic from the filename. For example:
95
- # `distorted IIDX-Readers-Unboxing.jpg: [#<MIME::Type: image/jpeg>]`
96
- #
97
- # Types#type_for can return multiple possibilities for a filename.
98
- # For example, an XML file: [application/xml, text/xml].
99
- mime = MIME::Types.type_for(@name).to_set
100
-
101
- # We can't proceed without a usable media type.
102
- # Look at the actual file iff the filename wasn't enough to guess.
103
- unless mime.empty?
104
- Jekyll.logger.debug(@tag_name, "Detected #{@name} media types: #{mime}")
105
- else
106
- # Did we fail to guess any MIME::Types from the given filename?
107
- # We're going to have to look at the actual file
108
- # (or at least its first four bytes).
109
- # `@mime` will be readable/writable in the FileMagic.open block context
110
- # since it was already defined in the outer scope.
111
- FileMagic.open(:mime) do |fm|
112
- # TODO: Support finding files in paths deeper than the Site source.
113
- # There's no good way to get the path here of the Markdown file
114
- # that included our Tag, so relative paths won't work if given
115
- # as just a filename. It should work if supplied like:
116
- # ![The coolest image ever](/2020/04/20/some-post/hahanofileextension)
117
- # This limitation is normally not a problem since we can guess
118
- # the MIME::Types just based on the filename.
119
- # It would be possible to supply the Markdown document's path
120
- # as an additional argument to {% distorted %} when converting
121
- # Markdown in `injection_of_love`, but I am resisting that
122
- # approach because it would make DD's Liquid and Markdown entrypoints
123
- # no longer exactly equivalent, and that's not okay with me.
124
- test_path = File.join(
125
- Jekyll::DistorteD::Floor::config(:source),
126
- Jekyll::DistorteD::Floor::config(:collections_dir),
127
- @name,
128
- )
129
- # The second argument makes fm.file return just the simple
130
- # MIME::Type String, e.g.:
131
- #
132
- # irb(main):006:1* fm.file('/home/okeeblow/IIDX-turntable.svg')
133
- # => "image/svg+xml; charset=us-ascii"
134
- # irb(main):009:1* fm.file('/home/okeeblow/IIDX-turntable.svg', true)
135
- # => "image/svg"
136
- #
137
- # However MIME::Types won't take short variants like 'image/svg',
138
- # so explicitly have FM return long types and split it ourself
139
- # on the semicolon:
140
- #
141
- # irb(main):038:0> "image/svg+xml; charset=us-ascii".split(';').first
142
- # => "image/svg+xml"
143
- mime = Set[MIME::Types[fm.file(@name, false).split(';'.freeze).first]]
144
- end
114
+ end
145
115
 
146
- # Did we still not get a type from FileMagic?
147
- unless mime
148
- if Jekyll::DistorteD::Floor::config(self.class.const_get(:CONFIG_ROOT), :last_resort)
149
- Jekyll.logger.debug(@tag_name, "Falling back to bare <img> for #{@name}")
150
- mime = Jekyll::DistorteD::Molecule::LastResort::MIME_TYPES
151
- else
152
- raise MediaTypeNotFoundError.new(@name)
116
+ # Returns a Set of DD MIME::Types descriving our file,
117
+ # optionally falling through to a plain file copy.
118
+ def type_mars
119
+ @type_mars ||= begin
120
+ mime = CHECKING::YOU::OUT(@name)
121
+ if mime.empty?
122
+ if Jekyll::DistorteD::Floor::config(Jekyll::DistorteD::Floor::CONFIG_ROOT, :last_resort)
123
+ mime = Jekyll::DistorteD::Molecule::LastResort::LOWER_WORLD
153
124
  end
154
125
  end
126
+ mime
155
127
  end
128
+ end
156
129
 
157
- # Array of drivers to try auto-plugging. Take a shallow copy first because
158
- # these will get popped off the end for plug attempts.
159
- media_molecules = MEDIA_MOLECULES.dup
160
-
161
- ## Media Driver Autoplugging
162
- #
163
- # Take the union of this file's detected MIME::Types and
164
- # the supported MEDIA_TYPES declared in each molecule.
165
- # Molecules will likely declare their Types with a regex:
166
- # https://rdoc.info/gems/mime-types/MIME%2FTypes:[]
167
- #
168
- #
169
- # Still-Image Mime::Types Example:
170
- # MIME::Types.type_for('IIDX-Readers-Unboxing.jpg')
171
- # => [#<MIME::Type: image/jpeg>]
172
- #
173
- # Video MIME::Types Example:
174
- # MIME::Types.type_for('play.mp4') => [
175
- # #<MIME::Type: application/mp4>,
176
- # #<MIME::Type: audio/mp4>,
177
- # #<MIME::Type: video/mp4>,
178
- # #<MIME::Type: video/vnd.objectvideo>
179
- # ]
180
- #
181
- #
182
- # Molecule declared-supported MIME::Types Example:
183
- # (huge list)
184
- # MIME_TYPES = MIME::Types[/^#{MEDIA_TYPE}/, :complete => true]
185
- #
186
- #
187
- # Detected & Declared MIME::Types Union Example:
188
- # MIME::Types.type_for('play.mp4') & MIME::Types[/^video/, :complete => true]
189
- # => [#<MIME::Type: video/mp4>, #<MIME::Type: video/vnd.objectvideo>]
190
- #
191
- # ^ This non-empty example union means we sould try this driver for this file.
192
- #
193
- #
194
- # Loop until we've found a match or tried all available drivers.
195
- loop do
196
- # Attempt to plug the last driver in the array of enabled drivers.
197
- molecule = media_molecules.pop
198
-
199
- # This will be nil once we've tried them all and run out and are on the last loop.
200
- if molecule == nil
201
- if Jekyll::DistorteD::Floor::config(self.class.const_get(:CONFIG_ROOT), :last_resort)
202
- Jekyll.logger.debug(@tag_name, "Falling back to a bare <img> for #{name}")
203
- @mime = Jekyll::DistorteD::Molecule::LastResort::MIME_TYPES
204
- molecule = Jekyll::DistorteD::Molecule::LastResort
205
- else
206
- raise MediaTypeNotImplementedError.new(@name)
207
- end
208
- end
209
-
210
- Jekyll.logger.debug(@tag_name, "Trying to plug #{@name} into #{molecule}")
211
-
212
- # We found a potentially-compatible driver iff the union set is non-empty.
213
- if not (mime & molecule.const_get(:MIME_TYPES)).empty?
214
- @mime = mime & molecule.const_get(:MIME_TYPES)
215
- Jekyll.logger.debug(@tag_name, "Enabling #{molecule} for #{@name}: #{mime}")
216
-
217
- # Override Invoker's stubs by prepending the driver's methods to our DD instance's singleton class.
218
- # https://devalot.com/articles/2008/09/ruby-singleton
219
- # `self.singleton_class.extend(molecule)` doesn't work in this context.
220
- self.singleton_class.instance_variable_set(:@media_molecule, molecule)
221
-
222
- # Set instance variables for the combined set of HTML element
223
- # attributes used for this media_type. The global set is defined in this file
224
- # (Invoker), and the media_type-specific set is appended to that during auto-plug.
225
- attrs = (self.singleton_class.const_get(:GLOBAL_ATTRS) + molecule.const_get(:ATTRS)).to_hash
226
- attrs.each_pair do |attr, val|
227
- # An attr supplied to the Liquid tag should override any from the config
228
- liquid_val = parsed_arguments&.dig(attr)
229
- # nil.to_s is '', so print 'nil' for readability.
230
- Jekyll.logger.debug("Liquid #{attr}", liquid_val || 'nil')
231
-
232
- if liquid_val.is_a?(String)
233
- # Symbolize String values of any attr that has a Molecule-defined list
234
- # of acceptable values, or — completely arbitrarily — any String value
235
- # shorter than an arbitrarily-chosen constant.
236
- # Otherwise freeze them.
237
- if (liquid_val.length <= ARBITRARY_ATTR_SYMBOL_STRING_LENGTH_BOUNDARY) or
238
- molecule.const_get(:ATTRS_VALUES).key?(attr)
239
- liquid_val = liquid_val&.to_sym
240
- elsif liquid_val.length > ARBITRARY_ATTR_SYMBOL_STRING_LENGTH_BOUNDARY
241
- # Will be default in Ruby 3.
242
- liquid_val = liquid_val&.freeze
243
- end
244
- end
245
-
246
- attrs[attr] = liquid_val
247
- end
248
-
249
- # Save attrs to our instance as the data source for Molecule::Abstract.attrs.
250
- @attrs = attrs
251
-
252
- # Plug the chosen Media Molecule!
253
- # Using Module#prepend puts the Molecule's ahead in the ancestor chain
254
- # of any defined here, or any defined in an `include`d module.
255
- (class <<self; prepend @media_molecule; end)
130
+ # Return any arguments given by the user to our Liquid tag.
131
+ # This method name is generic across all DD entrypoints so it can be
132
+ # referenced from lower layers in the pile.
133
+ def user_arguments
134
+ @liquid_liquid || Hash[]
135
+ end
256
136
 
257
- # Break out of the `loop`, a.k.a. stop auto-plugging!
258
- break
259
- end
137
+ # Decides which MediaMolecule is most appropriate for our file and returns it.
138
+ def media_molecule
139
+ available_molecules = TYPE_MOLECULES.keys.to_set & type_mars
140
+ # TODO: Handle multiple molecules for the same file
141
+ case available_molecules.length
142
+ when 0
143
+ raise MediaTypeNotImplementedError.new(@name)
144
+ when 1
145
+ return TYPE_MOLECULES[available_molecules.first].first
146
+ end
147
+ end
260
148
 
149
+ def plug
150
+ unless self.singleton_class.instance_variable_defined?(:@media_molecule)
151
+ self.singleton_class.instance_variable_set(:@media_molecule, media_molecule)
152
+ self.singleton_class.prepend(media_molecule)
153
+ Jekyll.logger.info(@name, "Plugging #{media_molecule}")
261
154
  end
262
155
  end
263
156
 
@@ -265,16 +158,18 @@ module Jekyll
265
158
  # https://github.com/jekyll/jekyll/blob/HEAD/lib/jekyll/renderer.rb
266
159
  # https://jekyllrb.com/tutorials/orderofinterpretation/
267
160
  def render(context)
161
+ plug
268
162
  render_to_output_buffer(context, '')
269
163
  end
270
164
 
271
165
  # A future Liquid version (5.0?) will call this function directly
272
166
  # instead of calling render()
273
167
  def render_to_output_buffer(context, output)
168
+ plug
274
169
  # Get Jekyll Site object back from tag rendering context registers so we
275
170
  # can get configuration data and path information from it and
276
171
  # then pass it along to our StaticFile subclass.
277
- site = context.registers[:site]
172
+ @site = context.registers[:site]
278
173
 
279
174
  # The rendering context's `first` page will be the one that invoked us.
280
175
  page_data = context.environments.first['page'.freeze]
@@ -282,12 +177,12 @@ module Jekyll
282
177
  #
283
178
  # Our subclass' additional args:
284
179
  # dest - The String path to the generated `url` folder of the page HTML output
285
- base = site.source
180
+ @base = @site.source
286
181
 
287
182
  # `relative_path` doesn't seem to always exist, but `path` does? idk.
288
183
  # I was testing with `relative_path` only with `_posts`, but it broke
289
184
  # when I invoked DD on a _page. Both have `path`.
290
- dir = File.dirname(page_data['path'.freeze])
185
+ @dir = File.dirname(page_data['path'.freeze])
291
186
 
292
187
  # Every one of Ruby's `File.directory?` / `Pathname.directory?` /
293
188
  # `FileTest.directory?` methods actually tests that path on the
@@ -298,67 +193,30 @@ module Jekyll
298
193
  # directory (like configured on cooltrainer) or a `.html`
299
194
  # (or other extension) like the default Jekyll config.
300
195
  # Get the dirname if the url is not a dir itself.
301
- @dd_dest = @url = page_data['url'.freeze]
302
- unless @dd_dest[-1] == Jekyll::DistorteD::Floor::PATH_SEPARATOR
303
- @dd_dest = File.dirname(@dd_dest)
196
+ @relative_dest = page_data['url'.freeze]
197
+ unless @relative_dest[-1] == Jekyll::DistorteD::Floor::PATH_SEPARATOR
198
+ @relative_dest = File.dirname(@relative_dest)
304
199
  # Append the trailing slash so we don't have to do it
305
200
  # in the Liquid templates.
306
- @dd_dest << Jekyll::DistorteD::Floor::PATH_SEPARATOR
201
+ @relative_dest << Jekyll::DistorteD::Floor::PATH_SEPARATOR
307
202
  end
308
203
 
309
- # Create an instance of the media-appropriate Jekyll::StaticFile subclass.
310
- #
311
- # StaticFile args:
312
- # site - The Jekyll Site object.
313
- # base - The String path to the Jekyll::Site.source, e.g. /home/okeeblow/Works/cooltrainer
314
- # dir - The String path between <base> and the source file, e.g. _posts/2018-10-15-super-cool-post
315
- # name - The String filename of the original media, e.g. cool.jpg
316
- # mime - The Set of MIME::Types of the original media.
317
- # attrs - The Set of attributes given to our Liquid tag, if any.
318
- # dd_dest - The String path under Site.dest to DD's top-level media output directory.
319
- # url - The URL of the page this tag is on.
320
- static_file = self.static_file(
321
- site,
322
- base,
323
- dir,
324
- @name,
325
- @mime,
326
- @attrs,
327
- @dd_dest,
328
- @url,
329
- )
330
-
331
204
  # Add our new file to the list that will be handled
332
205
  # by Jekyll's built-in StaticFile generator.
333
- # Our StaticFile children implement a write() that invokes DistorteD,
334
- # but this lets us avoid writing our own Generator.
335
- site.static_files << static_file
336
- end
337
-
338
- # Called by a Molecule-specific render() method since they will
339
- # all load their Liquid template files in the same way.
340
- # Bail out if this is not handled by the module we just mixed in.
341
- # Any media Molecule must override this to return an instance of
342
- # their media-type-appropriate StaticFile subclass.
343
- def static_file(site, base, dir, name, mime, attrs, dd_dest, url)
344
- raise MediaTypeNotImplementedError.new(name)
206
+ @site.static_files << self
207
+ output
345
208
  end
346
209
 
347
210
  # Generic Liquid template loader that will be used in every MediaMolecule.
348
211
  # Callers will call `render(**{:template => vars})` on the Object returned
349
212
  # by this method.
350
213
  def parse_template(site: nil, name: nil)
351
- site = site || Jekyll.sites.first
214
+ site = site || @site || Jekyll.sites.first
352
215
  begin
353
216
  # Use a given filename, or detect one based on media-type.
354
217
  if name.nil?
355
- # Template filename is based on the MEDIA_TYPE and/or SUB_TYPE declared
356
- # in the plugged MediaMolecule for the given input file.
357
- if self.singleton_class.const_defined?(:SUB_TYPE)
358
- name = "#{self.singleton_class.const_get(:SUB_TYPE)}.liquid".freeze
359
- else
360
- name = "#{self.singleton_class.const_get(:MEDIA_TYPE)}.liquid".freeze
361
- end
218
+ # e.g. Jekyll::DistorteD::Molecule::Image -> 'image.liquid'
219
+ name = "#{self.singleton_class.instance_variable_get(:@media_molecule).name.gsub(/^.*::/, '').downcase}.liquid".freeze
362
220
  elsif not name.include?('.liquid'.freeze)
363
221
  # Support filename arguments with and without file extension.
364
222
  # The given String might already be frozen, so concatenating
@@ -395,6 +253,7 @@ module Jekyll
395
253
  end
396
254
  end # parse_template
397
255
 
256
+
398
257
  end
399
258
  end
400
259
  end