module PictureTag
# Contains all possible HTML output format options. Auto is considered its
# own option.
module OutputFormats
# Generic functions common to all output formats.
class Basic
include ObjectiveElements
# Used for both the fallback image, and for the complete markup.
def build_base_img
img = SingleTag.new 'img'
attributes = PictureTag.html_attributes
img.attributes << attributes['img']
img.attributes << attributes['implicit']
fallback = build_fallback_image
add_src(img, fallback.uri)
add_alt(img, attributes['alt'])
img
end
def to_s
wrap(base_markup).to_s
end
private
# Handles various wrappers around basic markup
def wrap(markup)
if PictureTag.html_attributes['link']
markup = anchor_tag(markup)
markup = nomarkdown_wrapper(markup.to_s) if PictureTag.nomarkdown?
end
markup
end
# Media is the media query associated with the desired source image.
def build_srcset(source_image, format)
if PictureTag.preset['pixel_ratios']
Srcsets::PixelRatio.new(source_image, format)
else
Srcsets::Width.new(source_image, format)
end
end
# Extracting these functions to their own methods for easy overriding.
def add_src(element, uri)
element.src = uri
end
def add_srcset(element, srcset)
element.srcset = srcset.to_s
end
def add_sizes(element, srcset)
element.sizes = srcset.sizes if srcset.sizes
end
def add_alt(element, alt)
element.alt = alt if alt
end
def add_media(element, srcset)
element.media = srcset.media_attribute if srcset.media
end
# GeneratedImage class, not HTML
def build_fallback_image
return fallback_candidate if fallback_candidate.exists?
build_new_fallback_image
end
def fallback_candidate
@fallback_candidate ||= GeneratedImage.new(
source_file: PictureTag.source_images.first,
format: PictureTag.fallback_format,
width: PictureTag.fallback_width,
crop: PictureTag.crop,
gravity: PictureTag.gravity
)
end
def build_new_fallback_image
GeneratedImage.new(
source_file: PictureTag.source_images.first,
format: PictureTag.fallback_format,
width: checked_fallback_width,
crop: PictureTag.crop,
gravity: PictureTag.gravity
)
end
# Stops kramdown from molesting our output
# Must be given a string.
#
# Kramdown is super picky about the {::nomarkdown} extension-- we have to
# strip line breaks or nothing works.
def nomarkdown_wrapper(content)
"{::nomarkdown}#{content.delete("\n").gsub(/> , '><')}{:/nomarkdown}"
end
def anchor_tag(content)
anchor = DoubleTag.new 'a'
anchor.attributes << PictureTag.html_attributes['a']
anchor.href = PictureTag.html_attributes['link']
content.add_parent anchor
end
def source
PictureTag.source_images.first
end
def source_width
if PictureTag.crop
fallback_candidate.cropped_source_width
else
source.width
end
end
def checked_fallback_width
target = PictureTag.fallback_width
if target > source_width
Utils.warning "#{source.shortname} is smaller than the " \
"requested fallback width of #{target}px. Using #{source_width}" \
' px instead.'
source_width
else
target
end
end
end
end
end