diff --git a/lib/herb/engine/compiler.rb b/lib/herb/engine/compiler.rb index f662a9959..67c602aad 100644 --- a/lib/herb/engine/compiler.rb +++ b/lib/herb/engine/compiler.rb @@ -350,11 +350,14 @@ def process_erb_tag(node, skip_comment_check: false) end return if erb_graphql?(opening) - code = node.content.value.strip + raw_content = node.content.value + code = raw_content.strip if erb_output?(opening) process_erb_output(node, opening, code) else + code = "\n#{code}" if raw_content.start_with?("\n") + code = "#{code}\n" if raw_content.match?(/\n[ \t]*\z/) apply_trim(node, code) end end @@ -590,7 +593,11 @@ def apply_trim(node, code) if at_line_start? leading_space = extract_and_remove_leading_space! effective_leading_space = leading_space.empty? ? removed_whitespace : leading_space - right_space = Herb::Engine.heredoc?(code) ? "\n" : " \n" + right_space = if code.end_with?("\n") || Herb::Engine.heredoc?(code) + "\n" + else + " \n" + end @pending_leading_whitespace_insert_index = @tokens.length @pending_leading_whitespace = effective_leading_space if !effective_leading_space.empty? && follows_newline diff --git a/test/engine/whitespace_trimming_test.rb b/test/engine/whitespace_trimming_test.rb index c31f1501e..efaa51974 100644 --- a/test/engine/whitespace_trimming_test.rb +++ b/test/engine/whitespace_trimming_test.rb @@ -364,5 +364,17 @@ class WhitespaceTrimmingTest < Minitest::Spec assert_compiled_snapshot(template) assert_evaluated_snapshot(template, enforce_erubi_equality: true) end + + test "multi-line code block preserves line count parity with erubi" do + template = "<%\n x = 1\n y = 2\n%>\n<%= x %>" + + herb_engine = assert_compiled_snapshot(template) + erubi_engine = Erubi::Engine.new(template) + + assert_equal erubi_engine.src.lines.count, herb_engine.src.lines.count, + "Herb should preserve line count for multi-line code blocks.\n " \ + "Erubi (#{erubi_engine.src.lines.count} lines): #{erubi_engine.src.inspect}\n " \ + "Herb (#{herb_engine.src.lines.count} lines): #{herb_engine.src.inspect}" + end end end diff --git a/test/snapshots/engine/block_comments_test/test_0001_ruby_block_comments_with_=begin_and_=end_multiline_ff404c4e708f59f532b4042441e458ad.txt b/test/snapshots/engine/block_comments_test/test_0001_ruby_block_comments_with_=begin_and_=end_multiline_ff404c4e708f59f532b4042441e458ad.txt index 1bde0c723..3a7c2e170 100644 --- a/test/snapshots/engine/block_comments_test/test_0001_ruby_block_comments_with_=begin_and_=end_multiline_ff404c4e708f59f532b4042441e458ad.txt +++ b/test/snapshots/engine/block_comments_test/test_0001_ruby_block_comments_with_=begin_and_=end_multiline_ff404c4e708f59f532b4042441e458ad.txt @@ -3,10 +3,12 @@ source: "Engine::BlockCommentsTest#test_0001_ruby block comments with =begin and input: "{source: \"<%\\n=begin %>\\n This, while unusual, is a legal form of commenting.\\n<%\\n=end %>\\n
Hey there
\\n\", options: {}}" --- _buf = ::String.new; + =begin _buf << ' This, while unusual, is a legal form of commenting. '.freeze; + =end _buf << '
Hey there
diff --git a/test/snapshots/engine/block_comments_test/test_0002_ruby_block_comments_inside_erb_tags_95bcfa3f3e28634bf923f18df0cd38a1.txt b/test/snapshots/engine/block_comments_test/test_0002_ruby_block_comments_inside_erb_tags_95bcfa3f3e28634bf923f18df0cd38a1.txt index 26d9b7e78..b1c8903ae 100644 --- a/test/snapshots/engine/block_comments_test/test_0002_ruby_block_comments_inside_erb_tags_95bcfa3f3e28634bf923f18df0cd38a1.txt +++ b/test/snapshots/engine/block_comments_test/test_0002_ruby_block_comments_inside_erb_tags_95bcfa3f3e28634bf923f18df0cd38a1.txt @@ -3,9 +3,11 @@ source: "Engine::BlockCommentsTest#test_0002_ruby block comments inside erb tags input: "{source: \"<%\\n=begin\\nThis is a comment\\n=end\\n%>\\n

Content

\\n\", options: {}}" --- _buf = ::String.new; + =begin This is a comment -=end +=end + _buf << '

Content

'.freeze; diff --git a/test/snapshots/engine/block_comments_test/test_0003_ruby_block_comments_with_code_before_and_after_0ee0ba8a9a25359175b884cf66f37b2c.txt b/test/snapshots/engine/block_comments_test/test_0003_ruby_block_comments_with_code_before_and_after_0ee0ba8a9a25359175b884cf66f37b2c.txt index a99b44c90..01184dd3f 100644 --- a/test/snapshots/engine/block_comments_test/test_0003_ruby_block_comments_with_code_before_and_after_0ee0ba8a9a25359175b884cf66f37b2c.txt +++ b/test/snapshots/engine/block_comments_test/test_0003_ruby_block_comments_with_code_before_and_after_0ee0ba8a9a25359175b884cf66f37b2c.txt @@ -4,10 +4,12 @@ input: "{source: \"<% x = 1 %>\\n<%\\n=begin\\nMulti-line comment\\nspanning mul --- _buf = ::String.new; x = 1 + =begin Multi-line comment spanning multiple lines -=end +=end + y = 2 _buf << '
'.freeze; _buf << (x + y).to_s; _buf << '
diff --git a/test/snapshots/engine/block_comments_test/test_0007_ruby_block_comments_with_=begin_and_=end_mutliline_and_no_space_before_ERB_closing_tag_72379778fa34572e48b949a780f761b1.txt b/test/snapshots/engine/block_comments_test/test_0007_ruby_block_comments_with_=begin_and_=end_mutliline_and_no_space_before_ERB_closing_tag_72379778fa34572e48b949a780f761b1.txt index adb7e49a9..144f8e6cc 100644 --- a/test/snapshots/engine/block_comments_test/test_0007_ruby_block_comments_with_=begin_and_=end_mutliline_and_no_space_before_ERB_closing_tag_72379778fa34572e48b949a780f761b1.txt +++ b/test/snapshots/engine/block_comments_test/test_0007_ruby_block_comments_with_=begin_and_=end_mutliline_and_no_space_before_ERB_closing_tag_72379778fa34572e48b949a780f761b1.txt @@ -3,10 +3,12 @@ source: "Engine::BlockCommentsTest#test_0007_ruby block comments with =begin and input: "{source: \"<%\\n=begin%>\\n This, while unusual, is a legal form of commenting.\\n<%\\n=end%>\\n
Hey there
\\n\", options: {}}" --- _buf = ::String.new; + =begin _buf << ' This, while unusual, is a legal form of commenting. '.freeze; + =end _buf << '
Hey there
diff --git a/test/snapshots/engine/engine_test/test_0019_heredoc_in_code_tag_compiles_to_valid_Ruby_4af6472f81c8026291897a7a34e6ae0b.txt b/test/snapshots/engine/engine_test/test_0019_heredoc_in_code_tag_compiles_to_valid_Ruby_4af6472f81c8026291897a7a34e6ae0b.txt index 39be3c687..090bd0828 100644 --- a/test/snapshots/engine/engine_test/test_0019_heredoc_in_code_tag_compiles_to_valid_Ruby_4af6472f81c8026291897a7a34e6ae0b.txt +++ b/test/snapshots/engine/engine_test/test_0019_heredoc_in_code_tag_compiles_to_valid_Ruby_4af6472f81c8026291897a7a34e6ae0b.txt @@ -2,7 +2,9 @@ source: "Engine::EngineTest#test_0019_heredoc in code tag compiles to valid Ruby" input: "{source: \"<%\\n text = <<~TEXT\\n Hello, world!\\n TEXT\\n%>\\n\", options: {}}" --- -_buf = ::String.new; text = <<~TEXT +_buf = ::String.new; +text = <<~TEXT Hello, world! TEXT + _buf.to_s diff --git a/test/snapshots/engine/engine_test/test_0021_heredoc_with_dash_syntax_in_code_tag_compiles_to_valid_Ruby_61fc267bae73b15dae254d0d5f9fbe0e.txt b/test/snapshots/engine/engine_test/test_0021_heredoc_with_dash_syntax_in_code_tag_compiles_to_valid_Ruby_61fc267bae73b15dae254d0d5f9fbe0e.txt index 00793dd4b..0405f6037 100644 --- a/test/snapshots/engine/engine_test/test_0021_heredoc_with_dash_syntax_in_code_tag_compiles_to_valid_Ruby_61fc267bae73b15dae254d0d5f9fbe0e.txt +++ b/test/snapshots/engine/engine_test/test_0021_heredoc_with_dash_syntax_in_code_tag_compiles_to_valid_Ruby_61fc267bae73b15dae254d0d5f9fbe0e.txt @@ -2,7 +2,9 @@ source: "Engine::EngineTest#test_0021_heredoc with dash syntax in code tag compiles to valid Ruby" input: "{source: \"<%\\n text = <<-TEXT\\n Hello, world!\\n TEXT\\n%>\\n\", options: {}}" --- -_buf = ::String.new; text = <<-TEXT +_buf = ::String.new; +text = <<-TEXT Hello, world! TEXT + _buf.to_s diff --git a/test/snapshots/engine/engine_test/test_0022_heredoc_with_quoted_identifier_in_code_tag_compiles_to_valid_Ruby_c596f2621d8ae2223c3805e78ff1b3e3.txt b/test/snapshots/engine/engine_test/test_0022_heredoc_with_quoted_identifier_in_code_tag_compiles_to_valid_Ruby_c596f2621d8ae2223c3805e78ff1b3e3.txt index c6c198568..18e779c7e 100644 --- a/test/snapshots/engine/engine_test/test_0022_heredoc_with_quoted_identifier_in_code_tag_compiles_to_valid_Ruby_c596f2621d8ae2223c3805e78ff1b3e3.txt +++ b/test/snapshots/engine/engine_test/test_0022_heredoc_with_quoted_identifier_in_code_tag_compiles_to_valid_Ruby_c596f2621d8ae2223c3805e78ff1b3e3.txt @@ -2,7 +2,9 @@ source: "Engine::EngineTest#test_0022_heredoc with quoted identifier in code tag compiles to valid Ruby" input: "{source: \"<%\\n text = <<~'TEXT'\\n Hello, world!\\n TEXT\\n%>\\n\", options: {}}" --- -_buf = ::String.new; text = <<~'TEXT' +_buf = ::String.new; +text = <<~'TEXT' Hello, world! TEXT + _buf.to_s diff --git a/test/snapshots/engine/examples_compilation_test/test_0004_block_comment_compilation_d5c98b9f230e001f8aabf838d3774698.txt b/test/snapshots/engine/examples_compilation_test/test_0004_block_comment_compilation_d5c98b9f230e001f8aabf838d3774698.txt index c88d96943..eb96167ff 100644 --- a/test/snapshots/engine/examples_compilation_test/test_0004_block_comment_compilation_d5c98b9f230e001f8aabf838d3774698.txt +++ b/test/snapshots/engine/examples_compilation_test/test_0004_block_comment_compilation_d5c98b9f230e001f8aabf838d3774698.txt @@ -3,10 +3,12 @@ source: "Engine::ExamplesCompilationTest#test_0004_block comment compilation" input: "{source: \"<%\\n=begin %>\\n This, while unusual, is a legal form of commenting.\\n<%\\n=end %>\\n\\n
Content
\\n\", options: {escape: false}}" --- _buf = ::String.new; + =begin _buf << ' This, while unusual, is a legal form of commenting. '.freeze; + =end _buf << ' diff --git a/test/snapshots/engine/whitespace_trimming_test/test_0045_multi-line_code_block_preserves_line_count_parity_with_erubi_056ad410b82f521050ab536ab6d01f5f.txt b/test/snapshots/engine/whitespace_trimming_test/test_0045_multi-line_code_block_preserves_line_count_parity_with_erubi_056ad410b82f521050ab536ab6d01f5f.txt new file mode 100644 index 000000000..3143cbef1 --- /dev/null +++ b/test/snapshots/engine/whitespace_trimming_test/test_0045_multi-line_code_block_preserves_line_count_parity_with_erubi_056ad410b82f521050ab536ab6d01f5f.txt @@ -0,0 +1,10 @@ +--- +source: "Engine::WhitespaceTrimmingTest#test_0045_multi-line code block preserves line count parity with erubi" +input: "{source: \"<%\\n x = 1\\n y = 2\\n%>\\n<%= x %>\", options: {}}" +--- +_buf = ::String.new; +x = 1 + y = 2 + + _buf << (x).to_s; +_buf.to_s