Skip to content

Formatter: punctuation and inline closing tags pushed to own lines inside ERB blocks #1721

@tmaier

Description

@tmaier

Input:

<% if condition %>
  Created at <a href="<%= url %>">Acme</a>.
<% end %>

Output:

<% if condition %>
  Created at
  <a href="<%= url %>">Acme</a>
  .
<% end %>

Expected:

<% if condition %>
  Created at <a href="<%= url %>">Acme</a>.
<% end %>

Playground:

https://herb-tools.dev/playground?tab=format

Additional context:

Tested with @herb-tools/formatter@0.10.1.

Outside an ERB block the same line is preserved correctly:

<p>You are at <a href="/">Acme</a>.</p>            # untouched ✓
<p><em><%= name %></em> created an account.</p>   # untouched ✓
<p>
  Created at <a href="<%= url %>">Acme</a>.       # untouched ✓
</p>

But once the inline content is inside <% if %> … <% end %> (or any ERB control-flow block), the formatter splits the run at every inline-element boundary and pushes the trailing . onto its own line. In rendered HTML this is a real visual bug — newlines between inline content collapse to a single space, so the user sees Acme . (visible space before the period) and Created at\n<a>Acme</a> becomes a wider gap than authored.

Closing tags trigger this too: <em>name</em> created an account. inside an ERB block becomes:

<em>name</em>
created an account.

Related: #931 / #1266 fixed the ERB-tag + punctuation variant; this is the closing-HTML-tag + punctuation + closing-HTML-tag + following-text variant inside ERB blocks, which seems uncovered by isTextFlowNode / collectTextFlowRun.

Reproduced with:

echo '<% if condition %>
  Created at <a href="<%= url %>">Acme</a>.
<% end %>' > repro.html.erb
npx @herb-tools/formatter@0.10.1 repro.html.erb

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions