Add image block for HTML5-modified

This commit is contained in:
Gabriel Arazas 2023-11-24 20:31:25 +08:00
parent bb0e461197
commit 6e2c022c45
No known key found for this signature in database
GPG Key ID: ADE0C41DAB221FCC
2 changed files with 198 additions and 1 deletions

View File

@ -84,6 +84,56 @@ module Asciidoctor::Foodogsquared::Converters
html.to_html(indent: 2)
end
def convert_image(node)
html = Nokogiri::HTML5::DocumentFragment.parse <<~HTML
<figure>
<picture></picture>
</figure>
HTML
figure = html.first_element_child
picture = figure.first_element_child
add_common_attributes node, figure
node.attr?('sources') && add_sources_elem(node, picture, 'image')
target = node.attr 'target'
if (node.attr?('format', 'svg') || target.end_with?('.svg'))
if node.option? 'inline'
reader_opts = {
start: node.document.attr('imagesdir'),
normalize: true,
label: 'SVG',
warn_if_empty: true
}
figure.inner_html = node.read_contents target, reader_opts
elsif node.option? 'interactive'
picture.unlink
html.document.create_element 'object' do |object|
node.attr?('fallback') && object.add_child(add_img_elem(node, html))
add_attributes_from_node node, object, %w[width height]
object['type'] = 'image/svg+xml'
object['data'] = node.image_uri target
figure.add_child object
end
else
picture.add_child(add_img_elem(node, html))
end
else
picture.add_child(add_img_elem(node, html))
end
if node.title?
html.document.create_element 'figcaption' do |block|
block.inner_html = node.captioned_title
figure.add_child block
end
end
html.to_html(indent: 2)
end
# A modified version of the audio node except it can accept multiple
# sources.
def convert_audio(node)
@ -188,9 +238,10 @@ module Asciidoctor::Foodogsquared::Converters
end
def add_sources_elem(node, html, media_type)
src_attr = html.name == 'picture' ? 'srcset' : 'src'
sources = node.attr('sources', '').split(',').each do |src|
src = html.document.create_element 'source' do |block|
block['src'] = src
block[src_attr] = src
type = MIME::Types.type_for(src).find do |mime|
mime.media_type == media_type
@ -203,5 +254,13 @@ module Asciidoctor::Foodogsquared::Converters
[html, sources]
end
def add_img_elem(node, html)
html.document.create_element 'img' do |img|
add_attributes_from_node node, img, %w[width height]
img['src'] = node.attr 'target'
img['alt'] = node.alt
end
end
end
end

View File

@ -66,6 +66,144 @@ describe Asciidoctor::Foodogsquared::Converters::HTML5Modified do
(expect actual).to eq expected.chomp
end
it 'should have an image block with multiple <source>' do
input = <<~INPUT
image::hello.png[sources="hello.avif,hello.webp"]
INPUT
expected = <<~HTML
<figure>
<picture><source srcset="hello.avif" type="image/avif"><source srcset="hello.webp" type="image/webp"><img src="hello.png" alt="hello"></picture>
</figure>
HTML
actual = (Asciidoctor.convert input).chomp
(expect actual).to eq expected.chomp
end
it 'should have an image block with interactive SVG images' do
input = <<~INPUT
image::#{fixtures_file 'hello.svg'}[Interactive, opts=interactive]
INPUT
# rubocop:disable Layout/TrailingWhitespace
expected = <<~HTML
<figure>
<object type="image/svg+xml" data="#{fixtures_file 'hello.svg'}"></object></figure>
HTML
# rubocop:enable Layout/TrailingWhitespace
actual = (Asciidoctor.convert input).chomp
(expect actual).to eq expected.chomp
end
it 'should have an image block with interactive SVG images with a caption' do
input = <<~INPUT
:figure-caption!:
.SVG file
image::#{fixtures_file 'hello.svg'}[Interactive, opts=interactive]
INPUT
# rubocop:disable Layout/TrailingWhitespace
expected = <<~HTML
<figure>
<object type="image/svg+xml" data="#{fixtures_file 'hello.svg'}"></object><figcaption>SVG file</figcaption></figure>
HTML
# rubocop:enable Layout/TrailingWhitespace
actual = (Asciidoctor.convert input).chomp
(expect actual).to eq expected.chomp
end
it 'should have an image block with inline SVG images' do
input = <<~INPUT
image::#{fixtures_file 'hello.svg'}[Inline, opts=inline]
INPUT
expected = <<~HTML
<figure>#{File.read fixtures_file('hello.svg')}
</figure>
HTML
actual = (Asciidoctor.convert input).chomp
(expect actual).to eq expected.chomp
end
it 'should have an image block with inline SVG image with a caption' do
input = <<~INPUT
:figure-caption!:
.Inline SVG file
image::#{fixtures_file 'hello.svg'}[Inline, opts=inline]
INPUT
expected = <<~HTML
<figure>#{File.read fixtures_file('hello.svg')}<figcaption>Inline SVG file</figcaption></figure>
HTML
actual = (Asciidoctor.convert input).chomp
(expect actual).to eq expected.chomp
end
it 'should have an image block with multiple <source> with caption' do
input = <<~INPUT
:figure-caption!:
.A figure caption
image::hello.png[sources="hello.avif,hello.webp"]
INPUT
expected = <<~HTML
<figure>
<picture><source srcset="hello.avif" type="image/avif"><source srcset="hello.webp" type="image/webp"><img src="hello.png" alt="hello"></picture>
<figcaption>A figure caption</figcaption></figure>
HTML
actual = (Asciidoctor.convert input).chomp
(expect actual).to eq expected.chomp
end
it 'should have an image block with multiple <source>, a caption, an ID, and multiple roles' do
input = <<~INPUT
:figure-caption!:
[#image-id.whoa.there]
.A figure caption
image::hello.png[sources="hello.avif,hello.webp"]
INPUT
expected = <<~HTML
<figure id="image-id" class="whoa there">
<picture><source srcset="hello.avif" type="image/avif"><source srcset="hello.webp" type="image/webp"><img src="hello.png" alt="hello"></picture>
<figcaption>A figure caption</figcaption></figure>
HTML
actual = (Asciidoctor.convert input).chomp
(expect actual).to eq expected.chomp
end
it 'should have an image block with multiple <source>, a caption, an ID, and multiple roles with some attributes' do
input = <<~INPUT
:figure-caption!:
[#image-id.whoa.there]
.A figure caption
image::hello.png[sources="hello.avif,hello.webp", width=300, height=100]
INPUT
expected = <<~HTML
<figure id="image-id" class="whoa there">
<picture><source srcset="hello.avif" type="image/avif"><source srcset="hello.webp" type="image/webp"><img width="300" height="100" src="hello.png" alt="hello"></picture>
<figcaption>A figure caption</figcaption></figure>
HTML
actual = (Asciidoctor.convert input).chomp
(expect actual).to eq expected.chomp
end
it 'should have a video block with multiple <source>' do
input = <<~INPUT
video::hello.mp4[sources="hello.mp4,hello.webm"]