From 6e2c022c450e875affdad0e1227f327924006392 Mon Sep 17 00:00:00 2001 From: Gabriel Arazas Date: Fri, 24 Nov 2023 20:31:25 +0800 Subject: [PATCH] Add image block for HTML5-modified --- .../converters/html5-extended.rb | 61 +++++++- spec/html5_extended_converter.rb | 138 ++++++++++++++++++ 2 files changed, 198 insertions(+), 1 deletion(-) diff --git a/lib/asciidoctor/foodogsquared/converters/html5-extended.rb b/lib/asciidoctor/foodogsquared/converters/html5-extended.rb index 460e480..51b9b02 100644 --- a/lib/asciidoctor/foodogsquared/converters/html5-extended.rb +++ b/lib/asciidoctor/foodogsquared/converters/html5-extended.rb @@ -84,6 +84,56 @@ module Asciidoctor::Foodogsquared::Converters html.to_html(indent: 2) end + def convert_image(node) + html = Nokogiri::HTML5::DocumentFragment.parse <<~HTML +
+ +
+ 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 diff --git a/spec/html5_extended_converter.rb b/spec/html5_extended_converter.rb index c4d2174..34aadea 100644 --- a/spec/html5_extended_converter.rb +++ b/spec/html5_extended_converter.rb @@ -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 ' do + input = <<~INPUT + image::hello.png[sources="hello.avif,hello.webp"] + INPUT + + expected = <<~HTML +
+ hello +
+ 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 +
+ +
+ 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 +
+ +
SVG file
+ 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 +
#{File.read fixtures_file('hello.svg')} +
+ 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 +
#{File.read fixtures_file('hello.svg')}
Inline SVG file
+ HTML + + actual = (Asciidoctor.convert input).chomp + (expect actual).to eq expected.chomp + end + + it 'should have an image block with multiple with caption' do + input = <<~INPUT + :figure-caption!: + + .A figure caption + image::hello.png[sources="hello.avif,hello.webp"] + INPUT + + expected = <<~HTML +
+ hello +
A figure caption
+ HTML + + actual = (Asciidoctor.convert input).chomp + (expect actual).to eq expected.chomp + end + + it 'should have an image block with multiple , 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 +
+ hello +
A figure caption
+ HTML + + actual = (Asciidoctor.convert input).chomp + (expect actual).to eq expected.chomp + end + + it 'should have an image block with multiple , 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 +
+ hello +
A figure caption
+ HTML + + actual = (Asciidoctor.convert input).chomp + (expect actual).to eq expected.chomp + end + it 'should have a video block with multiple ' do input = <<~INPUT video::hello.mp4[sources="hello.mp4,hello.webm"]