Repository: haml/haml (Ruby)

Issue:
Whitespace removal with indentation
Hello.

Upgrading from 5.2.2 to 6.0.10, I find outer whitespace removal `>` doesn't remove some newlines.
A minimal example is the following.
```haml
- if true
  a
%br>
b
```
is compiled to
```html
a
<br>b
```

But, Haml 5.2.2 compiles it to
```html
a<br>b
```
, which is my expected output.


I produced this example using Haml 6.0.10
```
# haml version
6.0.10
```

Thank you.


Discussion:
Fixed in 6.0.11.
@k0kubun 
Thank you for fixing.
I confirm v6.0.11 works well for the above example, but I find a newline still remains when else block exists and if block is rendered.
As a new minimal example,
```haml
- if true
  a
- else
  b
%br>
c
```
will be
```html
 a
<br>c
```
though the output of v5.2.2 is
```html
a<br>c
```

Fixed in v6.0.12.
Thank you for so quick fixing!



Patch:
diff --git a/lib/haml/compiler/children_compiler.rb b/lib/haml/compiler/children_compiler.rb
index 5bbe6328d..1f6e480a8 100644
--- a/lib/haml/compiler/children_compiler.rb
+++ b/lib/haml/compiler/children_compiler.rb
@@ -12,15 +12,15 @@ def compile(node, &block)
         temple = [:multi]
         return temple if node.children.empty?
 
-        temple << :whitespace if prepend_whitespace?(node)
+        temple << [:whitespace] if prepend_whitespace?(node)
         node.children.each do |n|
           rstrip_whitespace!(temple) if nuke_prev_whitespace?(n)
           insert_newlines!(temple, n)
           temple << moving_lineno(n) { block.call(n) }
-          temple << :whitespace if insert_whitespace?(n)
+          temple << [:whitespace] if insert_whitespace?(n)
         end
         rstrip_whitespace!(temple) if nuke_inner_whitespace?(node)
-        confirm_whitespace(temple)
+        temple
       end
 
       private
@@ -56,17 +56,6 @@ def moving_lineno(node, &block)
         temple
       end
 
-      def confirm_whitespace(temple)
-        temple.map do |exp|
-          case exp
-          when :whitespace
-            [:static, "\n"]
-          else
-            exp
-          end
-        end
-      end
-
       def prepend_whitespace?(node)
         return false unless %i[comment tag].include?(node.type)
         !nuke_inner_whitespace?(node)
@@ -100,8 +89,14 @@ def nuke_outer_whitespace?(node)
       end
 
       def rstrip_whitespace!(temple)
-        if temple[-1] == :whitespace
-          temple.delete_at(-1)
+        case temple[0]
+        when :multi, :block
+          case temple[-1][0]
+          when :multi, :block
+            rstrip_whitespace!(temple[-1])
+          when :whitespace
+            temple.delete_at(-1)
+          end
         end
       end
 
diff --git a/lib/haml/engine.rb b/lib/haml/engine.rb
index 66e56e3e8..9983e15ac 100644
--- a/lib/haml/engine.rb
+++ b/lib/haml/engine.rb
@@ -8,6 +8,7 @@
 require 'haml/force_escapable'
 require 'haml/dynamic_merger'
 require 'haml/ambles'
+require 'haml/whitespace'
 
 module Haml
   class Engine < Temple::Engine
@@ -36,6 +37,7 @@ class Engine < Temple::Engine
     filter :ControlFlow
     use Ambles
     filter :MultiFlattener
+    use Whitespace
     filter :StaticMerger
     use DynamicMerger
     use :Generator, -> { options[:generator] }
diff --git a/lib/haml/whitespace.rb b/lib/haml/whitespace.rb
new file mode 100644
index 000000000..e77674467
--- /dev/null
+++ b/lib/haml/whitespace.rb
@@ -0,0 +1,8 @@
+# frozen_string_literal: true
+module Haml
+  class Whitespace < Temple::Filter
+    def on_whitespace
+      [:static, "\n"]
+    end
+  end
+end


Test patch:
diff --git a/test/haml/engine/whitespace_test.rb b/test/haml/engine/whitespace_test.rb
index cb9780afd..fe35e3e72 100644
--- a/test/haml/engine/whitespace_test.rb
+++ b/test/haml/engine/whitespace_test.rb
@@ -23,6 +23,17 @@
       HAML
     end
 
+    it 'removes top-level outer whitespaces with >' do
+      assert_render(<<-HTML.unindent, <<-HAML.unindent)
+        a<br>b
+      HTML
+        - if true
+          a
+        %br>
+        b
+      HAML
+    end
+
     it 'removes outer whitespace by > from inside of block' do
       assert_render(<<-HTML.unindent, <<-HAML.unindent)
         <span>a</span><span>