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 <figure> tag with a <figcaption> (possibly blank) as a
sibling. The <figcaption> can be marked up with links.
This commit is contained in:
Edward Loveall 2021-07-05 14:10:40 -04:00
parent 743d9e5fa9
commit f7a72fd2b5
No known key found for this signature in database
GPG Key ID: 789A4AE983AC8901
5 changed files with 97 additions and 6 deletions

View File

@ -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"),
]

View File

@ -87,6 +87,26 @@ describe PageContent do
html.should eq %(<p>This is <em>neat!</em></p>)
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
<figure>
<img src="https://cdn-images-1.medium.com/image.png">
<figcaption>A caption</figcaption>
</figure>
HTML
end
it "renders an H3" do
page = Page.new(nodes: [
Heading3.new(children: [
@ -207,3 +227,7 @@ describe PageContent do
html.should eq %(<a href="https://medium.com/u/abc123">Some User</a>)
end
end
def stripped_html(html : String)
html.gsub(/\n\s*/, "").strip
end

View File

@ -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

View File

@ -38,6 +38,14 @@ class PageContent < BaseComponent
raw "<!-- an Empty was rendered -->"
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

View File

@ -33,6 +33,12 @@ module Nodes
class Emphasis < Container
end
class Figure < Container
end
class FigureCaption < Container
end
class Heading3 < Container
end