Skip to content

Commit

Permalink
Compiler: add support for dashed attributes, more tests (#17)
Browse files Browse the repository at this point in the history
  • Loading branch information
noteflakes committed Apr 21, 2024
1 parent dab1e1e commit 5548f8a
Show file tree
Hide file tree
Showing 13 changed files with 105 additions and 12 deletions.
48 changes: 39 additions & 9 deletions lib/papercraft/compiler.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,22 @@
require 'escape_utils'
require 'sirop'

class Sirop::Sourcifier
# VISIT_PLANS.merge!({
# self: :emit_verbatim
# })

def visit_self_node(node)
emit_verbatim(node)
end

def visit_hash_node(node)
emit_code(node.opening_loc)
visit_comma_separated_nodes(node.elements)
emit_code(node.closing_loc)
end
end

class Papercraft::Compiler < Sirop::Sourcifier
def initialize
super
Expand Down Expand Up @@ -43,8 +59,12 @@ def html_embed_visit(node)
embed_visit(node, '#{CGI.escapeHTML(', ')}')
end

def tag_attr_embed_visit(node)
embed_visit(node, '#{', '}')
def tag_attr_embed_visit(node, key)
if key
embed_visit(node, '#{Papercraft.format_html_attr(', ')}')
else
embed_visit(node, '#{', '}')
end
end

def adjust_whitespace(loc)
Expand Down Expand Up @@ -135,21 +155,31 @@ 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(" ")
emit_tag_attribute_node(e.key)
emit_html('=\"')
emit_tag_attribute_node(e.value)
emit_html('\"')

if e.is_a?(Prism::AssocSplatNode)
embed_visit(e.value, '#{Papercraft.format_html_attrs(', ')}')
else
emit_tag_attribute_node(e.key, true)
emit_html('=\"')
emit_tag_attribute_node(e.value)
emit_html('\"')
end
end
end

def emit_tag_attribute_node(node)
def emit_tag_attribute_node(node, key = false)
case node
when Prism::StringNode, Prism::SymbolNode
@html_buffer << node.unescaped
value = node.unescaped
value = Papercraft.format_html_attr(value) if key
@html_buffer << value
else
tag_attr_embed_visit(node)
tag_attr_embed_visit(node, key)
end
end
end
11 changes: 11 additions & 0 deletions lib/papercraft/html.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,17 @@
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
Expand Down
1 change: 1 addition & 0 deletions test/fixtures/attributes.html
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<br/><h1 id="main-title">title</h1><div class="section"><h2>foo</h2></div><h3 id="baz" class="fuzz">bar</h3><h4 data-ref="42">Hi</h4><h5 class="klass" data-foo="bar">Bye</h5>
6 changes: 6 additions & 0 deletions test/fixtures/attributes_compiled.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
->(__buffer__) {
__buffer__ << "<br/><h1 id=\"main-title\">title</h1><div class=\"section\"><h2>foo</h2></div><h3 id=\"baz\" class=\"#{o.fuzz}\">bar</h3><h4 data-ref=\"42\">Hi</h4>"

attrs = { class: 'klass', data_foo: 'bar' }
__buffer__ << "<h5 #{Papercraft.format_html_attrs(attrs)}>Bye</h5>"
}
18 changes: 18 additions & 0 deletions test/fixtures/attributes_source.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
o = Object.new
def o.fuzz
'fuzz'
end

->() {
br
h1('title', id: 'main-title')
div(class: 'section') {
h2 'foo'
}
h3 'bar', id: 'baz', class: o.fuzz

h4 'Hi', data_ref: '42'

attrs = { class: 'klass', data_foo: 'bar' }
h5 'Bye', **attrs
}
2 changes: 1 addition & 1 deletion test/fixtures/basic_source.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,4 @@
end
}
}
}
}
1 change: 1 addition & 0 deletions test/fixtures/expr_text.html
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<h1>zoozoo - zoo</h1>
3 changes: 3 additions & 0 deletions test/fixtures/expr_text_compiled.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
->(__buffer__) {
__buffer__ << "<h1>#{CGI.escapeHTML("#{a.zoo} - zoo")}</h1>"
}
8 changes: 8 additions & 0 deletions test/fixtures/expr_text_source.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
a = Object.new
def a.zoo
'zoozoo'
end

->() {
h1 "#{a.zoo} - zoo"
}
1 change: 1 addition & 0 deletions test/fixtures/interspersed.html
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<h1>foo</h1><h2>bar</h2><h3>baz</h3>
7 changes: 7 additions & 0 deletions test/fixtures/interspersed_compiled.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
->(__buffer__) {
__buffer__ << "<h1>foo</h1>"
1 + 2
__buffer__ << "<h2>bar</h2>"
3 + 4
__buffer__ << "<h3>baz</h3>"
}
7 changes: 7 additions & 0 deletions test/fixtures/interspersed_source.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
-> {
h1 'foo'
1 + 2
h2 'bar'
3 + 4
h3 'baz'
}
4 changes: 2 additions & 2 deletions test/test_compiler.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ class CompilerTest < Minitest::Test
compiled_src = IO.read(compiled_fn).chomp
html = IO.read(html_fn)

define_method(:"test_compile_#{name}") do
define_method(:"test_compile_#{test_name}") do
proc = eval(original_src, binding, fn)
node = Sirop.to_ast(proc) { |str| }
assert_kind_of Prism::Node, node
Expand All @@ -25,7 +25,7 @@ class CompilerTest < Minitest::Test
assert_equal html, Papercraft.html(&proc).render
assert_equal compiled_src, compiled_code

compiled_proc = eval(compiled_code)
compiled_proc = eval(compiled_code, proc.binding)
assert_equal html, compiled_proc.call(+'')
end
end
Expand Down

0 comments on commit 5548f8a

Please sign in to comment.