Skip to content

Commit

Permalink
feat: Improve renderer (#93)
Browse files Browse the repository at this point in the history
  • Loading branch information
stephannv authored Oct 20, 2024
1 parent e13e6c0 commit 74c0731
Show file tree
Hide file tree
Showing 9 changed files with 131 additions and 30 deletions.
75 changes: 75 additions & 0 deletions spec/blueprint/html/renderer_spec.cr
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
require "../../spec_helper"

private class Component
include Blueprint::HTML

private def blueprint(&)
span { yield }
end
end

describe "renderer" do
it "renders Blueprint::HTML classes" do
actual_html = Blueprint::HTML.build do
render Component do
"Hello"
end
end

expected_html = "<span>Hello</span>"

actual_html.should eq expected_html
end

it "renders Blueprint::HTML instances" do
actual_html = Blueprint::HTML.build do
render Component.new do
"Hello"
end
end

expected_html = "<span>Hello</span>"

actual_html.should eq expected_html
end

it "renders strings" do
actual_html = Blueprint::HTML.build do
render "Hello"
end

expected_html = "Hello"

actual_html.should eq expected_html
end

it "renders blocks" do
actual_html = Blueprint::HTML.build do
render ->{ "He" + "llo" }
end

expected_html = "Hello"

actual_html.should eq expected_html
end

it "renders nothing when renderable is nil" do
actual_html = Blueprint::HTML.build do
render nil
end

expected_html = ""

actual_html.should eq expected_html
end

it "renders objects that respond `to_s`" do
actual_html = Blueprint::HTML.build do
render MarkdownLink.new("Example", "example.com")
end

expected_html = "[Example](example.com)"

actual_html.should eq expected_html
end
end
6 changes: 3 additions & 3 deletions src/blueprint/html.cr
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@ module Blueprint::HTML
include Blueprint::HTML::BlockRenderer
include Blueprint::HTML::BufferAppender
include Blueprint::HTML::ComponentRegistrar
include Blueprint::HTML::ComponentRenderer
include Blueprint::HTML::ElementRegistrar
include Blueprint::HTML::ElementRenderer
include Blueprint::HTML::Forms
include Blueprint::HTML::Helpers
include Blueprint::HTML::Renderer
include Blueprint::HTML::StandardElements
include Blueprint::HTML::StyleBuilder
include Blueprint::HTML::SVG
Expand Down Expand Up @@ -65,10 +65,10 @@ module Blueprint::HTML

{% if @type.has_method?(:around_render) %}
around_render do
blueprint { capture_content { yield } }
blueprint { __capture_content__ { yield } }
end
{% else %}
blueprint { capture_content { yield } }
blueprint { __capture_content__ { yield } }
{% end %}

{% if @type.has_method?(:after_render) %}
Expand Down
12 changes: 10 additions & 2 deletions src/blueprint/html/block_renderer.cr
Original file line number Diff line number Diff line change
@@ -1,9 +1,17 @@
module Blueprint::HTML::BlockRenderer
private def capture_content(&) : Nil
private def __capture_content__(&) : Nil
buffer_size_before_block_evaluation = @buffer.bytesize
content = yield
return if buffer_size_before_block_evaluation != @buffer.bytesize # return if something was written to buffer

append_to_buffer(content)
__append_to_buffer__(content)
end

private def __capture_content__(block : Proc) : Nil
buffer_size_before_block_evaluation = @buffer.bytesize
content = block.call
return if buffer_size_before_block_evaluation != @buffer.bytesize # return if something was written to buffer

__append_to_buffer__(content)
end
end
18 changes: 11 additions & 7 deletions src/blueprint/html/buffer_appender.cr
Original file line number Diff line number Diff line change
@@ -1,20 +1,24 @@
module Blueprint::HTML::BufferAppender
private def append_to_buffer(content : String)
escape(content, @buffer)
private def __append_to_buffer__(content : String)
__escape__(content, @buffer)
end

private def append_to_buffer(content : SafeObject)
private def __append_to_buffer__(content : Proc)
__capture_content__(content)
end

private def __append_to_buffer__(content : SafeObject)
content.to_s(@buffer)
end

private def append_to_buffer(content : Nil)
private def __append_to_buffer__(content : Nil)
end

private def append_to_buffer(content)
escape(content.to_s, @buffer)
private def __append_to_buffer__(content)
__escape__(content.to_s, @buffer)
end

private def escape(value : String, io : IO)
private def __escape__(value : String, io : IO)
::HTML.escape(value, io)
end
end
11 changes: 0 additions & 11 deletions src/blueprint/html/component_renderer.cr

This file was deleted.

4 changes: 2 additions & 2 deletions src/blueprint/html/element_registrar.cr
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ module Blueprint::HTML::ElementRegistrar
@buffer << "<{{tag.id}}"
__append_attributes__(attributes)
@buffer << ">"
capture_content { yield }
__capture_content__ { yield }
@buffer << "</{{tag.id}}>"
end

Expand All @@ -20,7 +20,7 @@ module Blueprint::HTML::ElementRegistrar
@buffer << "<{{tag.id}}"
__append_attributes__(attributes)
@buffer << ">"
append_to_buffer(__content__)
__append_to_buffer__(__content__)
@buffer << "</{{tag.id}}>"
end
end
Expand Down
4 changes: 2 additions & 2 deletions src/blueprint/html/element_renderer.cr
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ module Blueprint::HTML::ElementRenderer
@buffer << tag_name
__append_attributes__(attributes)
@buffer << ">"
capture_content { yield }
__capture_content__ { yield }
@buffer << "</"
@buffer << tag_name
@buffer << ">"
Expand All @@ -15,7 +15,7 @@ module Blueprint::HTML::ElementRenderer
@buffer << tag_name
__append_attributes__(attributes)
@buffer << ">"
append_to_buffer(__content__)
__append_to_buffer__(__content__)
@buffer << "</"
@buffer << tag_name
@buffer << ">"
Expand Down
25 changes: 25 additions & 0 deletions src/blueprint/html/renderer.cr
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
module Blueprint::HTML::Renderer
private def render(renderable : Blueprint::HTML) : Nil
renderable.to_s(@buffer)
end

private def render(renderable : Blueprint::HTML.class) : Nil
renderable.new.to_s(@buffer)
end

private def render(renderable : Blueprint::HTML, &) : Nil
renderable.to_s(@buffer) do
yield renderable
end
end

private def render(renderable : Blueprint::HTML.class, &) : Nil
renderable.new.to_s(@buffer) do
yield renderable
end
end

private def render(renderable) : Nil
__append_to_buffer__(renderable)
end
end
6 changes: 3 additions & 3 deletions src/blueprint/html/utils.cr
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module Blueprint::HTML::Utils
private def plain(content : String) : Nil
append_to_buffer(content)
__append_to_buffer__(content)
end

private def doctype : Nil
Expand All @@ -9,7 +9,7 @@ module Blueprint::HTML::Utils

private def comment(content) : Nil
@buffer << "<!--"
append_to_buffer(content)
__append_to_buffer__(content)
@buffer << "-->"
end

Expand All @@ -18,6 +18,6 @@ module Blueprint::HTML::Utils
end

private def raw(content : SafeObject) : Nil
append_to_buffer(content)
__append_to_buffer__(content)
end
end

0 comments on commit 74c0731

Please sign in to comment.