5a5f68bcf8
The API responds with a bunch of paragraphs which the client converts into Paragraph objects. This turns the paragraphs in a PostResponse's Paragraph objects into the form needed to render them on a page. This includes converting flat list elements into list elements nested by a UL. And adding a limited markups along the way. The array of paragraphs is passed to a recursive function. The function takes the first paragraph and either wraps the (marked up) contents in a container tag (like Paragraph or Heading3), and then moves onto the next tag. If it finds a list, it starts parsing the next paragraphs as a list instead. Originally, this was implemented like so: ```crystal paragraph = paragraphs.shift if list? convert_list([paragraph] + paragraphs) end ``` However, passing the `paragraphs` after adding it to the already shifted `paragraph` creates a new object. This means `paragraphs` won't be mutated and once the list is parsed, it starts with the next element of the list. Instead, the element is `shift`ed inside each converter. ```crystal if paragraphs.first == list? convert_list(paragraphs) end def convert_list(paragraphs) paragraph = paragraphs.shift # ... end ``` When rendering, there is an Empty and Container object. These represent a kind of "null object" for both leafs and parent objects respectively. They should never actually render. Emptys are filtered out, and Containers are never created explicitly but this will make the types pass. IFrames are a bit of a special case. Each IFrame has custom data on it that this system would need to be aware of. For now, instead of trying to parse the seemingly large number of iframe variations and dealing with embedded iframe problems, this will just keep track of the source page URL and send the user there with a link.
189 lines
4.6 KiB
Crystal
189 lines
4.6 KiB
Crystal
require "../spec_helper"
|
|
|
|
include Nodes
|
|
|
|
describe PageContent do
|
|
it "renders a single parent/child node structure" do
|
|
page = Page.new(nodes: [
|
|
Paragraph.new(children: [
|
|
Text.new(content: "hi"),
|
|
] of Child)
|
|
] of Child)
|
|
|
|
html = PageContent.new(page: page).render_to_string
|
|
|
|
html.should eq %(<p>hi</p>)
|
|
end
|
|
|
|
it "renders multiple childrens" do
|
|
page = Page.new(nodes: [
|
|
Paragraph.new(children: [
|
|
Text.new(content: "Hello, "),
|
|
Emphasis.new(children: [
|
|
Text.new(content: "World!")
|
|
] of Child)
|
|
] of Child),
|
|
UnorderedList.new(children: [
|
|
ListItem.new(children: [
|
|
Text.new(content: "List!")
|
|
] of Child),
|
|
ListItem.new(children: [
|
|
Text.new(content: "Again!"),
|
|
] of Child)
|
|
] of Child)
|
|
] of Child)
|
|
|
|
html = PageContent.new(page: page).render_to_string
|
|
|
|
html.should eq %(<p>Hello, <em>World!</em></p><ul><li>List!</li><li>Again!</li></ul>)
|
|
end
|
|
|
|
it "renders a blockquote" do
|
|
page = Page.new(nodes: [
|
|
BlockQuote.new(children: [
|
|
Text.new("Wayne Gretzky. Michael Scott.")
|
|
] of Child)
|
|
] of Child)
|
|
|
|
html = PageContent.new(page: page).render_to_string
|
|
|
|
html.should eq %(<blockquote>Wayne Gretzky. Michael Scott.</blockquote>)
|
|
end
|
|
|
|
it "renders code" do
|
|
page = Page.new(nodes: [
|
|
Code.new(children: [
|
|
Text.new("foo = bar")
|
|
] of Child)
|
|
] of Child)
|
|
|
|
html = PageContent.new(page: page).render_to_string
|
|
|
|
html.should eq %(<code>foo = bar</code>)
|
|
end
|
|
|
|
it "renders empasis" do
|
|
page = Page.new(nodes: [
|
|
Paragraph.new(children: [
|
|
Text.new(content: "This is "),
|
|
Emphasis.new(children: [
|
|
Text.new(content: "neat!")
|
|
] of Child),
|
|
] of Child),
|
|
] of Child)
|
|
|
|
html = PageContent.new(page: page).render_to_string
|
|
|
|
html.should eq %(<p>This is <em>neat!</em></p>)
|
|
end
|
|
|
|
it "renders an H3" do
|
|
page = Page.new(nodes: [
|
|
Heading3.new(children: [
|
|
Text.new(content: "Title!"),
|
|
] of Child),
|
|
] of Child)
|
|
|
|
html = PageContent.new(page: page).render_to_string
|
|
|
|
html.should eq %(<h3>Title!</h3>)
|
|
end
|
|
|
|
it "renders an H4" do
|
|
page = Page.new(nodes: [
|
|
Heading4.new(children: [
|
|
Text.new(content: "In Conclusion..."),
|
|
] of Child),
|
|
] of Child)
|
|
|
|
html = PageContent.new(page: page).render_to_string
|
|
|
|
html.should eq %(<h4>In Conclusion...</h4>)
|
|
end
|
|
|
|
it "renders an image" do
|
|
page = Page.new(nodes: [
|
|
Paragraph.new(children: [
|
|
Image.new(src: "image.png"),
|
|
] of Child)
|
|
] of Child)
|
|
|
|
html = PageContent.new(page: page).render_to_string
|
|
|
|
html.should eq %(<p><img src="https://cdn-images-1.medium.com/image.png"></p>)
|
|
end
|
|
|
|
it "renders an iframe container" do
|
|
page = Page.new(nodes: [
|
|
Paragraph.new(children: [
|
|
IFrame.new(href: "https://example.com"),
|
|
] of Child)
|
|
] of Child)
|
|
|
|
html = PageContent.new(page: page).render_to_string
|
|
|
|
html.should eq %(<p><div class="embedded"><a href="https://example.com">Click to visit embedded content</a></div></p>)
|
|
end
|
|
|
|
it "renders an ordered list" do
|
|
page = Page.new(nodes: [
|
|
OrderedList.new(children: [
|
|
ListItem.new(children: [Text.new("One")] of Child),
|
|
ListItem.new(children: [Text.new("Two")] of Child),
|
|
] of Child),
|
|
] of Child)
|
|
|
|
html = PageContent.new(page: page).render_to_string
|
|
|
|
html.should eq %(<ol><li>One</li><li>Two</li></ol>)
|
|
end
|
|
|
|
it "renders an preformatted text" do
|
|
page = Page.new(nodes: [
|
|
Paragraph.new(children: [
|
|
Text.new("Hello, world!"),
|
|
] of Child),
|
|
] of Child)
|
|
|
|
html = PageContent.new(page: page).render_to_string
|
|
|
|
html.should eq %(<p>Hello, world!</p>)
|
|
end
|
|
|
|
it "renders an preformatted text" do
|
|
page = Page.new(nodes: [
|
|
Preformatted.new(children: [
|
|
Text.new("New\nline"),
|
|
] of Child),
|
|
] of Child)
|
|
|
|
html = PageContent.new(page: page).render_to_string
|
|
|
|
html.should eq %(<pre>New\nline</pre>)
|
|
end
|
|
|
|
it "renders strong text" do
|
|
page = Page.new(nodes: [
|
|
Strong.new(children: [
|
|
Text.new("Oh yeah!"),
|
|
] of Child),
|
|
] of Child)
|
|
|
|
html = PageContent.new(page: page).render_to_string
|
|
|
|
html.should eq %(<strong>Oh yeah!</strong>)
|
|
end
|
|
|
|
it "renders an unordered list" do
|
|
page = Page.new(nodes: [
|
|
UnorderedList.new(children: [
|
|
ListItem.new(children: [Text.new("Apple")] of Child),
|
|
ListItem.new(children: [Text.new("Banana")] of Child),
|
|
] of Child),
|
|
] of Child)
|
|
|
|
html = PageContent.new(page: page).render_to_string
|
|
|
|
html.should eq %(<ul><li>Apple</li><li>Banana</li></ul>)
|
|
end
|
|
end
|