[ruby-core:91248] [Ruby trunk Feature#15538] Erb indenting / unindenting trim mode

From: kimmo.lehto@...
Date: 2019-01-24 12:05:02 UTC
List: ruby-core #91248
Issue #15538 has been updated by kke (Kimmo Lehto).

Description updated

Fixed the 2 -> 4 indentation in the bad example and added the "stop indenting" closing tag `|%>` which would be fine by me.

`<%|=` inside `<%|` would result in:

example code:
```
1
<%|- (2..3).each do |num| -%>
  <%= num %>: <%|= "foo\nbar\n" |%>
<%|- end -%>
4
```

expected output:

```
1
2: foo
    bar
3: foo
    bar
4
```

This would be excellent when rendering partials.


The line:

```
  <%= num %>: <%|= "foo\nbar\n" |%>
```

Would generate:

```
  3: foo
      bar
```

which would be reindented by the surrounding block and end up as:

```
3: foo
    bar
```


This is bit of a problem when the `<%|=` is used without any leading "indentation reference point":

```
1
<%|- (2..3).each do |num| -%>
  <%|= num |%>
<%| end %>
4
```

Because reindentation works by finding the least indented row and use that as the reference point, the lines with `<%|= num |%>` do not contain anything less indented, and thus will be reindented by the surrounding block to the left edge, but I think the outcome is still as expected, the `<%|=` was just used pointlessly.


----------------------------------------
Feature #15538: Erb indenting / unindenting trim mode
https://bugs.ruby-lang.org/issues/15538#change-76494

* Author: kke (Kimmo Lehto)
* Status: Feedback
* Priority: Normal
* Assignee: 
* Target version: 
----------------------------------------
In `Erb`, would it be possible to add a new trim mode that would indent the following content to match the depth of the tag? The tag could for example be `<%|` and it would be enabled using `Erb.new(template, trim_mode: '|')`

## Reason

Something like this would be easy to follow:

``` ruby
1
<%- [2, 3, 4].each do |num| -%>
  <%- unless num == 3 -%>
    <%= num %>
  <%- end -%>
<%- end -%>
5
```

But unfortunately it will render with "extra" indentation:

```
1
    2
    4
5
```

Currently, to avoid this, you have to write your template using either no indentation:

```
1
<%- [2, 3, 4].each do |num| -%>
<%- unless num == 3 -%>
<%= num %>
<%- end -%>
<%- end -%>
5
```

Or a weird jumpy indentation:

```
1
<%- [2, 3, 4].each do |num| -%>
  <%- unless num == 3 -%>
<%= num %>
  <%- end -%>
<%- end -%>
5
```

With the `|`  trim mode it could be written as:

```ruby
1
<%|- [2, 3, 4].each do |num| -%>
  <%- unless num == 3 -%>
    <%= num %>
  <%- end -%>
<%|- end -%>
5
```

And it would output as desired without the "extra" indentation:

```
1
2
4
5
```

## Using with `=`

It would also be handy if the `|` could be used with `<%=`, perhaps `<%|=`, this would be excellent for example when templating YAML's:

```yaml
<%- bar_content = "- abc\n- " -def" -%>
foo:
  bar: 
    <%|= bar_content |%>
```

Which would produce something like:

```yaml
foo:
  bar:
    - abc
    - def
```

Instead of the invalid YAML:

```yaml
foo:
  bar:
    - abc
- def
```

Currently there's no way to accomplish this without manually counting the leading spaces and using something like:

```yaml
<%- bar_content = "- abc\n- " -def" -%>
foo:
  bar:
    <%= bar_content.gsub(/(?<!\A)^(?!$)/m, ' ' * 4) %>
```





-- 
https://bugs.ruby-lang.org/

Unsubscribe: <mailto:ruby-core-request@ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-core>

In This Thread

Prev Next