Skip to content

Commit

Permalink
Compiler: add support for #emit with Proc (#17)
Browse files Browse the repository at this point in the history
  • Loading branch information
noteflakes committed May 9, 2024
1 parent 29fd60e commit 0847c68
Show file tree
Hide file tree
Showing 5 changed files with 46 additions and 30 deletions.
58 changes: 28 additions & 30 deletions lib/papercraft/compiler.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ def render_emit_call(o, *a, **b, &block)
when nil
# do nothing
when ::Proc
raise NotImplementedError
Papercraft.html(&o).render(*a, **b, &block)
else
o.to_s
end
Expand All @@ -49,20 +49,22 @@ def inject_buffer_parameter(node)
node.inject_parameters('__buffer__')
end

def emit(str)
if @embed_mode
@embed_buffer << str
else
@buffer << str
end
end

def embed_visit(node, pre = '', post = '')
tmp_last_loc_start = @last_loc_start
tmp_last_loc_end = @last_loc_end
@last_loc_start = loc_start(node.location)
@last_loc_end = loc_end(node.location)

@embed_mode = true
@embed_buffer = +''
tmp_buffer = @buffer
@buffer = +''
visit(node)
@embed_mode = false
@html_buffer << "#{pre}#{@embed_buffer}#{post}"
@html_buffer << "#{pre}#{@buffer}#{post}"
@buffer = tmp_buffer

@last_loc_start = tmp_last_loc_start
@last_loc_end = tmp_last_loc_end
end

def html_embed_visit(node)
Expand All @@ -77,10 +79,6 @@ def tag_attr_embed_visit(node, key)
end
end

def adjust_whitespace(loc)
super(loc) if !@embed_mode
end

def emit_code(loc, semicolon: false)
flush_html_buffer if !@embed_mode
super
Expand All @@ -105,7 +103,7 @@ def flush_html_buffer
end

def visit_call_node(node)
return super if node.receiver
return super if node.receiver || @embed_mode

@html_location_start ||= node.location

Expand Down Expand Up @@ -160,9 +158,6 @@ def emit_tag_inner_text(node)
end

def emit_tag_attributes(node, attrs)
# puts
# p emit_tag_attributes: node, attrs: attrs

attrs.elements.each do |e|
emit_html(" ")

Expand All @@ -188,17 +183,6 @@ def emit_tag_attribute_node(node, key = false)
end
end

def emit_html_text(node)
args = node.arguments&.arguments
return nil if !args

emit_tag_inner_text(args[0])
end

def emit_html_emit(node)
embed_visit(node.arguments, '#{Papercraft.render_emit_call(', ')}')
end

def emit_html_tag(node)
inner_text, attrs = tag_args(node)
block = node.block
Expand All @@ -216,4 +200,18 @@ def emit_html_tag(node)
emit_tag_open_close(node, attrs)
end
end

def emit_html_text(node)
args = node.arguments&.arguments
return nil if !args

emit_tag_inner_text(args[0])
end

def emit_html_emit(node)
args = node.arguments&.arguments
return nil if !args

embed_visit(node.arguments, '#{Papercraft.render_emit_call(', ')}')
end
end
1 change: 1 addition & 0 deletions test/fixtures/compiler/emit_proc.html
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<p>foo</p><p>42</p><br/><q>bar</q>
3 changes: 3 additions & 0 deletions test/fixtures/compiler/emit_proc_compiled.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
->(__buffer__) {
__buffer__ << "#{Papercraft.render_emit_call(pr1)}#{Papercraft.render_emit_call(pr2, 42)}<br/>#{Papercraft.render_emit_call(-> { q 'bar' })}"
}
9 changes: 9 additions & 0 deletions test/fixtures/compiler/emit_proc_source.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
pr1 = -> { p 'foo' }
pr2 = ->(x) { p x }

->() {
emit pr1
emit pr2, 42
br
emit -> { q 'bar' }
}
5 changes: 5 additions & 0 deletions test/test_compiler.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,17 @@ class CompilerTest < Minitest::Test
compiled_code = Papercraft::Compiler.new.compile(node)
puts compiled_code if ENV['DEBUG'] == '1'

# render source proc
assert_equal html, Papercraft.html(&proc).render

# compile
assert_equal compiled_src, compiled_code

compiled_proc = eval(compiled_code, proc.binding)
compiled_html = +''
compiled_proc.call(compiled_html)

# render compiled proc
assert_equal html, compiled_html
end
end
Expand Down

0 comments on commit 0847c68

Please sign in to comment.