Class: Kramdown::Converter::Liquid
- Inherits:
-
Base
- Object
- Base
- Kramdown::Converter::Liquid
- Defined in:
- lib/distorted-jekyll/md_injection.rb
Instance Method Summary collapse
- #attrs(el, type = :img) ⇒ Object
-
#children(el, type) ⇒ Object
The incoming parsed Markdown tree will include many spurious elements, like container paragraph elements and the list item elements when parsing DD Grid style Markdown.
-
#convert(el) ⇒ Object
Kramdown entry point.
- #distorted(attrs) ⇒ Object
-
#to_attrs(k, v) ⇒ Object
Convert Markdown element attributes to a string key=value, except for ‘src` (DD-specific).
Instance Method Details
#attrs(el, type = :img) ⇒ Object
218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 |
# File 'lib/distorted-jekyll/md_injection.rb', line 218 def attrs(el, type = :img) matched = [] if el.is_a? Enumerable # Support an Array of elements... el.each { |child| matched.push(*attrs(child, type)) } else # ...or a tree of elements. if el.type.equal? type # Images won't have a `:value` — only `:attr`s — and the only # important things in their `:options` (e.g. IAL contents) # will be duplicated in `class` or some other `:attr` anyway. # Those things should be added here if this is ever used in a # more generic context than just parsing the image tags. matched << el.attr unless el.attr.empty? end unless el.children.empty? # Keep looking even if this element was one we are looking for. el.children.each { |child| matched.push(*attrs(child, type)) } end end matched end |
#children(el, type) ⇒ Object
The incoming parsed Markdown tree will include many spurious elements, like container paragraph elements and the list item elements when parsing DD Grid style Markdown. Use this function to map a tree of arbitrary elements to a flat list of elements of a single type.
191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 |
# File 'lib/distorted-jekyll/md_injection.rb', line 191 def children(el, type) matched = [] if el.is_a? Enumerable # We might want to run this against an Array output from an # earlier invokation of this method. el.each { |item| matched.push(*children(item, type)) } elsif el.type.equal? type # If we find the type we're looking for, stop and return it. # Let it bring its children along with it instead of recursing # into them. This will let us match container-only elements # such as <li> by type without considering the type of its children, # for situation where its children are really what we want. matched.push(el) else # Otherwise keep looking down the tree. unless el.children.empty? el.children.each { |child| matched.push(*children(child, type)) } end end matched end |
#convert(el) ⇒ Object
Kramdown entry point
263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 |
# File 'lib/distorted-jekyll/md_injection.rb', line 263 def convert(el) # The parsed "images" may also be audio, video, or some other # media type. There is only one Markdown image tag, however. imgs = children(el, :img) # Enable conceptual-grouping (BLOCKS) mode if the count of list item # elements matches the count of image elements in our # chunk of Markdown. Technically I should check to make sure each # image is the child of one of those list items, # but this is way easier until I (hopefully never) find a parsing # corner-case where this doesn't hold up. lists = children(el, :li) list_imgs = lists.map{|li| children(li, :img)}.flatten case lists.count when 0..1 # Render one (1) image/video/whatever. This behavior is the same # regardless if the image is in a single-item list or just by itself. distorted(attrs(imgs.first)&.first&.merge({ # Images default to `attention` cropping for desktop/mobile versatility. # Override this for single images unless a cropping value was already set. 'crop'.freeze => attrs(imgs.first)&.first&.dig('crop'.freeze) || 'none'.freeze, })) else # Render a conceptual group (DD::BLOCKS) if imgs.count != list_imgs.count # Sanity check :img count vs :img-in-:li count. # We should support the corner case where the regex matches # multiple consecutive lines, but with mixed list item status, # e.g. a solo image abuts a conceptual group and gets globbed # into a single match. # For now, however: raise "MD->img regex returned an unequal number of listed and unlisted tags." end "{% distort -%}\n#{list_imgs.map{|img| distorted(*attrs(img))}.join("\n")}\n{% enddistort %}" end end |
#distorted(attrs) ⇒ Object
258 259 260 |
# File 'lib/distorted-jekyll/md_injection.rb', line 258 def distorted(attrs) "{% distorted #{attrs.map{|k,v| to_attrs(k, v)}.join(' ')} %}" end |
#to_attrs(k, v) ⇒ Object
Convert Markdown element attributes to a string key=value, except for ‘src` (DD-specific)
248 249 250 251 252 253 254 255 256 |
# File 'lib/distorted-jekyll/md_injection.rb', line 248 def to_attrs(k, v) # DistorteD prefers the media filename as a positional argument, # not a named kwarg. if k == 'src' v.to_s else k.to_s + '="' + v.to_s + '"' end end |