diff --git a/src/extract.c b/src/extract.c index 8f88fd4f5..297afe0fe 100644 --- a/src/extract.c +++ b/src/extract.c @@ -39,7 +39,26 @@ void herb_extract_ruby_to_buffer_with_semicolons(const char* source, hb_buffer_T case TOKEN_ERB_CONTENT: { if (skip_erb_content == false) { - hb_buffer_append(output, token->value); + bool is_inline_comment = false; + + if (!is_comment_tag && token->value != NULL) { + const char* content = token->value; + + while (*content == ' ' || *content == '\t') { + content++; + } + + if (*content == '#' && token->location.start.line == token->location.end.line) { + is_comment_tag = true; + is_inline_comment = true; + } + } + + if (is_inline_comment) { + hb_buffer_append_whitespace(output, range_length(token->range)); + } else { + hb_buffer_append(output, token->value); + } } else { hb_buffer_append_whitespace(output, range_length(token->range)); } diff --git a/test/c/test_extract.c b/test/c/test_extract.c index 07a9d27ce..d707622c7 100644 --- a/test/c/test_extract.c +++ b/test/c/test_extract.c @@ -89,6 +89,62 @@ TEST(extract_ruby_issue_135_if_without_condition) free(result); END +TEST(extract_ruby_inline_comment_same_line) + char* source = "<% if true %><% # Comment here %><% end %>"; + char* result = herb_extract_ruby_with_semicolons(source); + + ck_assert_str_eq(result, " if true ; end "); + + free(result); +END + +TEST(extract_ruby_inline_comment_with_newline) + char* source = "<% if true %><% # Comment here %>\n<% end %>"; + char* result = herb_extract_ruby_with_semicolons(source); + + char expected[] = " if true ; \n end "; + ck_assert_str_eq(result, expected); + + free(result); +END + +TEST(extract_ruby_inline_comment_with_spaces) + char* source = "<% # Comment %> <% code %>"; + char* result = herb_extract_ruby_with_semicolons(source); + + ck_assert_str_eq(result, " code "); + + free(result); +END + +TEST(extract_ruby_inline_comment_multiline) + char* source = "<% # Comment\nmore %> <% code %>"; + char* result = herb_extract_ruby_with_semicolons(source); + + char expected[] = " # Comment\nmore ; code "; + ck_assert_str_eq(result, expected); + + free(result); +END + +TEST(extract_ruby_inline_comment_between_code) + char* source = "<% if true %><% # Comment here %><%= hello %><% end %>"; + char* result = herb_extract_ruby_with_semicolons(source); + + ck_assert_str_eq(result, " if true ; hello ; end "); + + free(result); +END + +TEST(extract_ruby_inline_comment_complex) + char* source = "<% # Comment here %><% if true %><% # Comment here %><%= hello %><% end %>"; + char* result = herb_extract_ruby_with_semicolons(source); + + ck_assert_str_eq(result, " if true ; hello ; end "); + + free(result); +END + TCase *extract_tests(void) { TCase *extract = tcase_create("Extract"); @@ -101,6 +157,12 @@ TCase *extract_tests(void) { tcase_add_test(extract, extract_ruby_empty_erb_same_line); tcase_add_test(extract, extract_ruby_comments_skipped); tcase_add_test(extract, extract_ruby_issue_135_if_without_condition); + tcase_add_test(extract, extract_ruby_inline_comment_same_line); + tcase_add_test(extract, extract_ruby_inline_comment_with_newline); + tcase_add_test(extract, extract_ruby_inline_comment_with_spaces); + tcase_add_test(extract, extract_ruby_inline_comment_multiline); + tcase_add_test(extract, extract_ruby_inline_comment_between_code); + tcase_add_test(extract, extract_ruby_inline_comment_complex); return extract; } diff --git a/test/parser/erb_test.rb b/test/parser/erb_test.rb index 623272aa3..4306ec697 100644 --- a/test/parser/erb_test.rb +++ b/test/parser/erb_test.rb @@ -228,5 +228,35 @@ class ERBTest < Minitest::Spec <% end %> HTML end + + test "inline ruby comment on same line" do + assert_parsed_snapshot(%(<% if true %><% # Comment here %><% end %>)) + end + + test "inline ruby comment with newline" do + assert_parsed_snapshot(<<~HTML) + <% if true %><% # Comment here %> + <% end %> + HTML + end + + test "inline ruby comment between code" do + assert_parsed_snapshot(%(<% if true %><% # Comment here %><%= hello %><% end %>)) + end + + test "inline ruby comment before and between code" do + assert_parsed_snapshot(%(<% # Comment here %><% if true %><% # Comment here %><%= hello %><% end %>)) + end + + test "inline ruby comment with spaces" do + assert_parsed_snapshot(%(<% # Comment %> <% code %>)) + end + + test "inline ruby comment multiline" do + assert_parsed_snapshot(<<~HTML) + <% # Comment + more %> <% code %> + HTML + end end end diff --git a/test/snapshots/parser/erb_test/test_0041_inline_ruby_comment_on_same_line_ac08c4aa2dc65416c853e466ace0ef3e.txt b/test/snapshots/parser/erb_test/test_0041_inline_ruby_comment_on_same_line_ac08c4aa2dc65416c853e466ace0ef3e.txt new file mode 100644 index 000000000..cb7e82068 --- /dev/null +++ b/test/snapshots/parser/erb_test/test_0041_inline_ruby_comment_on_same_line_ac08c4aa2dc65416c853e466ace0ef3e.txt @@ -0,0 +1,24 @@ +--- +source: "Parser::ERBTest#test_0041_inline ruby comment on same line" +input: "<% if true %><% # Comment here %><% end %>" +--- +@ DocumentNode (location: (1:0)-(1:42)) +└── children: (1 item) + └── @ ERBIfNode (location: (1:0)-(1:42)) + ├── tag_opening: "<%" (location: (1:0)-(1:2)) + ├── content: " if true " (location: (1:2)-(1:11)) + ├── tag_closing: "%>" (location: (1:11)-(1:13)) + ├── statements: (1 item) + │ └── @ ERBContentNode (location: (1:13)-(1:33)) + │ ├── tag_opening: "<%" (location: (1:13)-(1:15)) + │ ├── content: " # Comment here " (location: (1:15)-(1:31)) + │ ├── tag_closing: "%>" (location: (1:31)-(1:33)) + │ ├── parsed: true + │ └── valid: true + │ + ├── subsequent: ∅ + └── end_node: + └── @ ERBEndNode (location: (1:33)-(1:42)) + ├── tag_opening: "<%" (location: (1:33)-(1:35)) + ├── content: " end " (location: (1:35)-(1:40)) + └── tag_closing: "%>" (location: (1:40)-(1:42)) \ No newline at end of file diff --git a/test/snapshots/parser/erb_test/test_0042_inline_ruby_comment_with_newline_8dd8241832b9d58cebd54c96f2194351.txt b/test/snapshots/parser/erb_test/test_0042_inline_ruby_comment_with_newline_8dd8241832b9d58cebd54c96f2194351.txt new file mode 100644 index 000000000..53d498492 --- /dev/null +++ b/test/snapshots/parser/erb_test/test_0042_inline_ruby_comment_with_newline_8dd8241832b9d58cebd54c96f2194351.txt @@ -0,0 +1,33 @@ +--- +source: "Parser::ERBTest#test_0042_inline ruby comment with newline" +input: |2- +<% if true %><% # Comment here %> +<% end %> +--- +@ DocumentNode (location: (1:0)-(3:0)) +└── children: (2 items) + ├── @ ERBIfNode (location: (1:0)-(2:9)) + │ ├── tag_opening: "<%" (location: (1:0)-(1:2)) + │ ├── content: " if true " (location: (1:2)-(1:11)) + │ ├── tag_closing: "%>" (location: (1:11)-(1:13)) + │ ├── statements: (2 items) + │ │ ├── @ ERBContentNode (location: (1:13)-(1:33)) + │ │ │ ├── tag_opening: "<%" (location: (1:13)-(1:15)) + │ │ │ ├── content: " # Comment here " (location: (1:15)-(1:31)) + │ │ │ ├── tag_closing: "%>" (location: (1:31)-(1:33)) + │ │ │ ├── parsed: true + │ │ │ └── valid: true + │ │ │ + │ │ └── @ HTMLTextNode (location: (1:33)-(2:0)) + │ │ └── content: "\n" + │ │ + │ ├── subsequent: ∅ + │ └── end_node: + │ └── @ ERBEndNode (location: (2:0)-(2:9)) + │ ├── tag_opening: "<%" (location: (2:0)-(2:2)) + │ ├── content: " end " (location: (2:2)-(2:7)) + │ └── tag_closing: "%>" (location: (2:7)-(2:9)) + │ + │ + └── @ HTMLTextNode (location: (2:9)-(3:0)) + └── content: "\n" \ No newline at end of file diff --git a/test/snapshots/parser/erb_test/test_0043_inline_ruby_comment_between_code_5ea7fdc5882d9a26c3fc4c6166ce834c.txt b/test/snapshots/parser/erb_test/test_0043_inline_ruby_comment_between_code_5ea7fdc5882d9a26c3fc4c6166ce834c.txt new file mode 100644 index 000000000..23b458b3e --- /dev/null +++ b/test/snapshots/parser/erb_test/test_0043_inline_ruby_comment_between_code_5ea7fdc5882d9a26c3fc4c6166ce834c.txt @@ -0,0 +1,31 @@ +--- +source: "Parser::ERBTest#test_0043_inline ruby comment between code" +input: "<% if true %><% # Comment here %><%= hello %><% end %>" +--- +@ DocumentNode (location: (1:0)-(1:54)) +└── children: (1 item) + └── @ ERBIfNode (location: (1:0)-(1:54)) + ├── tag_opening: "<%" (location: (1:0)-(1:2)) + ├── content: " if true " (location: (1:2)-(1:11)) + ├── tag_closing: "%>" (location: (1:11)-(1:13)) + ├── statements: (2 items) + │ ├── @ ERBContentNode (location: (1:13)-(1:33)) + │ │ ├── tag_opening: "<%" (location: (1:13)-(1:15)) + │ │ ├── content: " # Comment here " (location: (1:15)-(1:31)) + │ │ ├── tag_closing: "%>" (location: (1:31)-(1:33)) + │ │ ├── parsed: true + │ │ └── valid: true + │ │ + │ └── @ ERBContentNode (location: (1:33)-(1:45)) + │ ├── tag_opening: "<%=" (location: (1:33)-(1:36)) + │ ├── content: " hello " (location: (1:36)-(1:43)) + │ ├── tag_closing: "%>" (location: (1:43)-(1:45)) + │ ├── parsed: true + │ └── valid: true + │ + ├── subsequent: ∅ + └── end_node: + └── @ ERBEndNode (location: (1:45)-(1:54)) + ├── tag_opening: "<%" (location: (1:45)-(1:47)) + ├── content: " end " (location: (1:47)-(1:52)) + └── tag_closing: "%>" (location: (1:52)-(1:54)) \ No newline at end of file diff --git a/test/snapshots/parser/erb_test/test_0044_inline_ruby_comment_before_and_between_code_ea519c99685fc73f63e18a1934a2d2d6.txt b/test/snapshots/parser/erb_test/test_0044_inline_ruby_comment_before_and_between_code_ea519c99685fc73f63e18a1934a2d2d6.txt new file mode 100644 index 000000000..ac0594bd0 --- /dev/null +++ b/test/snapshots/parser/erb_test/test_0044_inline_ruby_comment_before_and_between_code_ea519c99685fc73f63e18a1934a2d2d6.txt @@ -0,0 +1,38 @@ +--- +source: "Parser::ERBTest#test_0044_inline ruby comment before and between code" +input: "<% # Comment here %><% if true %><% # Comment here %><%= hello %><% end %>" +--- +@ DocumentNode (location: (1:0)-(1:74)) +└── children: (2 items) + ├── @ ERBContentNode (location: (1:0)-(1:20)) + │ ├── tag_opening: "<%" (location: (1:0)-(1:2)) + │ ├── content: " # Comment here " (location: (1:2)-(1:18)) + │ ├── tag_closing: "%>" (location: (1:18)-(1:20)) + │ ├── parsed: true + │ └── valid: true + │ + └── @ ERBIfNode (location: (1:20)-(1:74)) + ├── tag_opening: "<%" (location: (1:20)-(1:22)) + ├── content: " if true " (location: (1:22)-(1:31)) + ├── tag_closing: "%>" (location: (1:31)-(1:33)) + ├── statements: (2 items) + │ ├── @ ERBContentNode (location: (1:33)-(1:53)) + │ │ ├── tag_opening: "<%" (location: (1:33)-(1:35)) + │ │ ├── content: " # Comment here " (location: (1:35)-(1:51)) + │ │ ├── tag_closing: "%>" (location: (1:51)-(1:53)) + │ │ ├── parsed: true + │ │ └── valid: true + │ │ + │ └── @ ERBContentNode (location: (1:53)-(1:65)) + │ ├── tag_opening: "<%=" (location: (1:53)-(1:56)) + │ ├── content: " hello " (location: (1:56)-(1:63)) + │ ├── tag_closing: "%>" (location: (1:63)-(1:65)) + │ ├── parsed: true + │ └── valid: true + │ + ├── subsequent: ∅ + └── end_node: + └── @ ERBEndNode (location: (1:65)-(1:74)) + ├── tag_opening: "<%" (location: (1:65)-(1:67)) + ├── content: " end " (location: (1:67)-(1:72)) + └── tag_closing: "%>" (location: (1:72)-(1:74)) \ No newline at end of file diff --git a/test/snapshots/parser/erb_test/test_0045_inline_ruby_comment_with_spaces_dafcc25fbfcf9f288255b916fabd9e02.txt b/test/snapshots/parser/erb_test/test_0045_inline_ruby_comment_with_spaces_dafcc25fbfcf9f288255b916fabd9e02.txt new file mode 100644 index 000000000..dd5bc0c80 --- /dev/null +++ b/test/snapshots/parser/erb_test/test_0045_inline_ruby_comment_with_spaces_dafcc25fbfcf9f288255b916fabd9e02.txt @@ -0,0 +1,22 @@ +--- +source: "Parser::ERBTest#test_0045_inline ruby comment with spaces" +input: "<% # Comment %> <% code %>" +--- +@ DocumentNode (location: (1:0)-(1:27)) +└── children: (3 items) + ├── @ ERBContentNode (location: (1:0)-(1:16)) + │ ├── tag_opening: "<%" (location: (1:0)-(1:2)) + │ ├── content: " # Comment " (location: (1:2)-(1:14)) + │ ├── tag_closing: "%>" (location: (1:14)-(1:16)) + │ ├── parsed: true + │ └── valid: true + │ + ├── @ HTMLTextNode (location: (1:16)-(1:17)) + │ └── content: " " + │ + └── @ ERBContentNode (location: (1:17)-(1:27)) + ├── tag_opening: "<%" (location: (1:17)-(1:19)) + ├── content: " code " (location: (1:19)-(1:25)) + ├── tag_closing: "%>" (location: (1:25)-(1:27)) + ├── parsed: true + └── valid: true \ No newline at end of file diff --git a/test/snapshots/parser/erb_test/test_0046_inline_ruby_comment_multiline_9fe85e396a5cf0edf3b455ed6637bd91.txt b/test/snapshots/parser/erb_test/test_0046_inline_ruby_comment_multiline_9fe85e396a5cf0edf3b455ed6637bd91.txt new file mode 100644 index 000000000..fe65b3571 --- /dev/null +++ b/test/snapshots/parser/erb_test/test_0046_inline_ruby_comment_multiline_9fe85e396a5cf0edf3b455ed6637bd91.txt @@ -0,0 +1,28 @@ +--- +source: "Parser::ERBTest#test_0046_inline ruby comment multiline" +input: |2- +<% # Comment +more %> <% code %> +--- +@ DocumentNode (location: (1:0)-(3:0)) +└── children: (4 items) + ├── @ ERBContentNode (location: (1:0)-(2:7)) + │ ├── tag_opening: "<%" (location: (1:0)-(1:2)) + │ ├── content: " # Comment + │ more " (location: (1:2)-(2:5)) + │ ├── tag_closing: "%>" (location: (2:5)-(2:7)) + │ ├── parsed: true + │ └── valid: true + │ + ├── @ HTMLTextNode (location: (2:7)-(2:8)) + │ └── content: " " + │ + ├── @ ERBContentNode (location: (2:8)-(2:18)) + │ ├── tag_opening: "<%" (location: (2:8)-(2:10)) + │ ├── content: " code " (location: (2:10)-(2:16)) + │ ├── tag_closing: "%>" (location: (2:16)-(2:18)) + │ ├── parsed: true + │ └── valid: true + │ + └── @ HTMLTextNode (location: (2:18)-(3:0)) + └── content: "\n" \ No newline at end of file