From f7a72fd2b5f54540c4c40c0b372041201d35a42d Mon Sep 17 00:00:00 2001 From: Edward Loveall Date: Mon, 5 Jul 2021 14:10:40 -0400 Subject: [PATCH] Render image inside a figure with a caption Most images have a caption (or at least have the option of being captioned). Instead of displaying the raw image, it's not rendered inside a
tag with a
(possibly blank) as a sibling. The
can be marked up with links. --- spec/classes/paragraph_converter_spec.cr | 47 +++++++++++++++++++++++- spec/components/page_content_spec.cr | 24 ++++++++++++ src/classes/paragraph_converter.cr | 18 ++++++--- src/components/page_content.cr | 8 ++++ src/models/nodes.cr | 6 +++ 5 files changed, 97 insertions(+), 6 deletions(-) diff --git a/spec/classes/paragraph_converter_spec.cr b/spec/classes/paragraph_converter_spec.cr index 14faef2..fcf37b6 100644 --- a/spec/classes/paragraph_converter_spec.cr +++ b/spec/classes/paragraph_converter_spec.cr @@ -158,6 +158,48 @@ describe ParagraphConverter do result.should eq expected end + it "converts an IMG to a Figure" do + paragraph = PostResponse::Paragraph.from_json <<-JSON + { + "text": "Image by someuser", + "type": "IMG", + "markups": [ + { + "title": "", + "type": "A", + "href": "https://unsplash.com/@someuser", + "userId": null, + "start": 9, + "end": 17, + "rel": "photo-creator", + "anchorType": "LINK" + } + ], + "href": null, + "iframe": null, + "layout": "INSET_CENTER", + "metadata": { + "id": "image.png", + "originalWidth": 618, + "originalHeight": 682 + } + } + JSON + expected = [ + Figure.new(children: [ + Image.new(src: "image.png"), + FigureCaption.new(children: [ + Text.new("Image by "), + Anchor.new(href: "https://unsplash.com/@someuser", text: "someuser"), + ] of Child), + ] of Child), + ] + + result = ParagraphConverter.new.convert([paragraph]) + + result.should eq expected + end + it "converts all the tags" do paragraphs = Array(PostResponse::Paragraph).from_json <<-JSON [ @@ -260,7 +302,10 @@ describe ParagraphConverter do BlockQuote.new([Text.new("text")] of Child), UnorderedList.new([ListItem.new([Text.new("text")] of Child)] of Child), OrderedList.new([ListItem.new([Text.new("text")] of Child)] of Child), - Image.new(src: "1*miroimage.png"), + Figure.new(children: [ + Image.new(src: "1*miroimage.png"), + FigureCaption.new(children: [Text.new("text")] of Child), + ] of Child), IFrame.new(href: "https://example.com"), ] diff --git a/spec/components/page_content_spec.cr b/spec/components/page_content_spec.cr index ff25dac..a3c1f2b 100644 --- a/spec/components/page_content_spec.cr +++ b/spec/components/page_content_spec.cr @@ -87,6 +87,26 @@ describe PageContent do html.should eq %(

This is neat!

) end + it "renders a figure and figure caption" do + page = Page.new(nodes: [ + Figure.new(children: [ + Image.new(src: "image.png"), + FigureCaption.new(children: [ + Text.new("A caption") + ] of Child), + ] of Child), + ] of Child) + + html = PageContent.new(page: page).render_to_string + + html.should eq stripped_html <<-HTML +
+ +
A caption
+
+ HTML + end + it "renders an H3" do page = Page.new(nodes: [ Heading3.new(children: [ @@ -207,3 +227,7 @@ describe PageContent do html.should eq %(Some User) end end + +def stripped_html(html : String) + html.gsub(/\n\s*/, "").strip +end diff --git a/src/classes/paragraph_converter.cr b/src/classes/paragraph_converter.cr index 1288a04..071a742 100644 --- a/src/classes/paragraph_converter.cr +++ b/src/classes/paragraph_converter.cr @@ -29,11 +29,7 @@ class ParagraphConverter end when PostResponse::ParagraphType::IMG paragraph = paragraphs.shift - if metadata = paragraph.metadata - node = Image.new(src: metadata.id) - else - node = Empty.new - end + node = convert_img(paragraph) when PostResponse::ParagraphType::OLI list_items = convert_oli(paragraphs) node = OrderedList.new(children: list_items) @@ -76,4 +72,16 @@ class ParagraphConverter [] of Child end end + + private def convert_img(paragraph : PostResponse::Paragraph) : Child + if metadata = paragraph.metadata + caption_markup = MarkupConverter.convert(paragraph.text, paragraph.markups) + Figure.new(children: [ + Image.new(src: metadata.id), + FigureCaption.new(children: caption_markup) + ] of Child) + else + Empty.new + end + end end diff --git a/src/components/page_content.cr b/src/components/page_content.cr index 52c4eb3..1a50d29 100644 --- a/src/components/page_content.cr +++ b/src/components/page_content.cr @@ -38,6 +38,14 @@ class PageContent < BaseComponent raw "" end + def render_child(node : Figure) + figure { render_children(node.children) } + end + + def render_child(node : FigureCaption) + figcaption { render_children(node.children) } + end + def render_child(node : Heading3) h3 { render_children(node.children) } end diff --git a/src/models/nodes.cr b/src/models/nodes.cr index b533099..cb1b873 100644 --- a/src/models/nodes.cr +++ b/src/models/nodes.cr @@ -33,6 +33,12 @@ module Nodes class Emphasis < Container end + class Figure < Container + end + + class FigureCaption < Container + end + class Heading3 < Container end