From 29fd60ece28e18435a453cfb88a87983d6af8056 Mon Sep 17 00:00:00 2001 From: Sharon Rosner Date: Wed, 8 May 2024 08:47:04 +0200 Subject: [PATCH] Compiler: add support for #emit (#17) --- lib/papercraft/compiler.rb | 69 +++++++++++++++----- lib/papercraft/html.rb | 11 ---- test/fixtures/compiler/emit_text.html | 1 + test/fixtures/compiler/emit_text_compiled.rb | 3 + test/fixtures/compiler/emit_text_source.rb | 7 ++ 5 files changed, 64 insertions(+), 27 deletions(-) create mode 100644 test/fixtures/compiler/emit_text.html create mode 100644 test/fixtures/compiler/emit_text_compiled.rb create mode 100644 test/fixtures/compiler/emit_text_source.rb diff --git a/lib/papercraft/compiler.rb b/lib/papercraft/compiler.rb index 788786b..52adbba 100644 --- a/lib/papercraft/compiler.rb +++ b/lib/papercraft/compiler.rb @@ -5,6 +5,32 @@ require 'sirop' class Papercraft::Compiler < Sirop::Sourcifier + module AuxMethods + def format_html_attr(tag) + tag.to_s.tr('_', '-') + end + + def format_html_attrs(attrs) + attrs.reduce(+'') do |html, (k, v)| + html << ' ' if !html.empty? + html << "#{format_html_attr(k)}=\"#{v}\"" + end + end + + def render_emit_call(o, *a, **b, &block) + case o + when nil + # do nothing + when ::Proc + raise NotImplementedError + else + o.to_s + end + end + end + + Papercraft.extend(AuxMethods) + def initialize super @html_buffer = +'' @@ -85,24 +111,13 @@ def visit_call_node(node) case node.name when :text - return emit_html_text(node) - end - - inner_text, attrs = tag_args(node) - block = node.block - - if inner_text - emit_tag_open(node, attrs) - emit_tag_inner_text(inner_text) - emit_tag_close(node) - elsif block - emit_tag_open(node, attrs) - visit(block.body) - @html_location_start ||= node.block.closing_loc - emit_tag_close(node) + emit_html_text(node) + when :emit + emit_html_emit(node) else - emit_tag_open_close(node, attrs) + emit_html_tag(node) end + @html_location_end = node.location end @@ -179,4 +194,26 @@ def emit_html_text(node) 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 + + if inner_text + emit_tag_open(node, attrs) + emit_tag_inner_text(inner_text) + emit_tag_close(node) + elsif block + emit_tag_open(node, attrs) + visit(block.body) + @html_location_start ||= node.block.closing_loc + emit_tag_close(node) + else + emit_tag_open_close(node, attrs) + end + end end diff --git a/lib/papercraft/html.rb b/lib/papercraft/html.rb index 192f2b0..5e1702e 100644 --- a/lib/papercraft/html.rb +++ b/lib/papercraft/html.rb @@ -4,17 +4,6 @@ require 'cgi' module Papercraft - def self.format_html_attr(tag) - tag.to_s.tr('_', '-') - end - - def self.format_html_attrs(attrs) - attrs.reduce(+'') do |html, (k, v)| - html << ' ' if !html.empty? - html << "#{format_html_attr(k)}=\"#{v}\"" - end - end - # HTML Markup extensions module HTML include Tags diff --git a/test/fixtures/compiler/emit_text.html b/test/fixtures/compiler/emit_text.html new file mode 100644 index 0000000..086c7d9 --- /dev/null +++ b/test/fixtures/compiler/emit_text.html @@ -0,0 +1 @@ +foo&bar
bar&baz \ No newline at end of file diff --git a/test/fixtures/compiler/emit_text_compiled.rb b/test/fixtures/compiler/emit_text_compiled.rb new file mode 100644 index 0000000..1f9db6b --- /dev/null +++ b/test/fixtures/compiler/emit_text_compiled.rb @@ -0,0 +1,3 @@ +->(__buffer__) { + __buffer__ << "#{Papercraft.render_emit_call('foo&bar')}
#{Papercraft.render_emit_call(x)}" +} diff --git a/test/fixtures/compiler/emit_text_source.rb b/test/fixtures/compiler/emit_text_source.rb new file mode 100644 index 0000000..3474366 --- /dev/null +++ b/test/fixtures/compiler/emit_text_source.rb @@ -0,0 +1,7 @@ +x = 'bar&baz' + +->() { + emit 'foo&bar' + br + emit x +}