ruby-core@ruby-lang.org archive (unofficial mirror)
 help / color / mirror / Atom feed
* [ruby-core:91103] [Ruby trunk Feature#15538] Erb indenting / unindenting trim mode
       [not found] <redmine.issue-15538.20190115133510@ruby-lang.org>
@ 2019-01-15 13:35 ` kimmo.lehto
  2019-01-15 14:10 ` [ruby-core:91105] " takashikkbn
                   ` (11 subsequent siblings)
  12 siblings, 0 replies; 13+ messages in thread
From: kimmo.lehto @ 2019-01-15 13:35 UTC (permalink / raw)
  To: ruby-core

Issue #15538 has been reported by kke (Kimmo Lehto).

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

* Author: kke (Kimmo Lehto)
* Status: Open
* 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 looks nice:

``` ruby
- horse
<% ['cat', 'dog', 'goldfish'].each do |pet| %>
  <% unless pet == 'goldfish' %>
    - <%= pet %>
  <% end %>
<% end %>
```

But unfortunately it will render with "extra" indentation:

```
- horse
   - cat
   - dog
```

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

```ruby
- horse
<%| ['cat', 'dog', 'goldfish'].each do |pet| %>
....
<% end %>
```

And it would output as desired without the "extra" indentation. Currently, to produce such output, you have write your erb template without indentation or using a jumpy mixed indentation (code and content have different indentation levels but are interleaved) and it's not a very user/editor friendly way to work.

## 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 = "- something\n- something else" %>
foo:
  bar: 
    <%|= bar_content %>
```

Which would produce something like:

```yaml
foo:
  bar:
    - something
    - something else
```

Instead of the invalid:

```yaml
foo:
  bar:
    - something
- something else
```

Currently there's no way to accomplish this without manually counting the leading spaces, as it's not possible to detect the column where `<%=` appeared.



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

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [ruby-core:91105] [Ruby trunk Feature#15538] Erb indenting / unindenting trim mode
       [not found] <redmine.issue-15538.20190115133510@ruby-lang.org>
  2019-01-15 13:35 ` [ruby-core:91103] [Ruby trunk Feature#15538] Erb indenting / unindenting trim mode kimmo.lehto
@ 2019-01-15 14:10 ` takashikkbn
  2019-01-15 15:22 ` [ruby-core:91106] " merch-redmine
                   ` (10 subsequent siblings)
  12 siblings, 0 replies; 13+ messages in thread
From: takashikkbn @ 2019-01-15 14:10 UTC (permalink / raw)
  To: ruby-core

Issue #15538 has been updated by k0kubun (Takashi Kokubun).

Status changed from Open to Feedback

It's hard to understand your proposal for me. Could you fix the following two parts first?

1. Do not use "...." in the template. We are talking about a feature to change indentation and the indentation you imagine in "...." is not clear to me.
2. Clarify the trim_mode you intended to use for each template, and make sure your template actually matches the result you show. At least your first template and its result does not seem to match in the default trim_mode.

```
$ cat a.rb
src = <<-EOS
- horse
<% ['cat', 'dog', 'goldfish'].each do |pet| %>
  <% unless pet == 'goldfish' %>
    - <%= pet %>
  <% end %>
<% end %>
EOS

puts ERB.new(src).result
$ ruby -rerb a.rb
- horse


    - cat



    - dog




```

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

* 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 looks nice:

``` ruby
- horse
<% ['cat', 'dog', 'goldfish'].each do |pet| %>
  <% unless pet == 'goldfish' %>
    - <%= pet %>
  <% end %>
<% end %>
```

But unfortunately it will render with "extra" indentation:

```
- horse
   - cat
   - dog
```

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

```ruby
- horse
<%| ['cat', 'dog', 'goldfish'].each do |pet| %>
....
<% end %>
```

And it would output as desired without the "extra" indentation. Currently, to produce such output, you have write your erb template without indentation or using a jumpy mixed indentation (code and content have different indentation levels but are interleaved) and it's not a very user/editor friendly way to work.

## 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 = "- something\n- something else" %>
foo:
  bar: 
    <%|= bar_content %>
```

Which would produce something like:

```yaml
foo:
  bar:
    - something
    - something else
```

Instead of the invalid:

```yaml
foo:
  bar:
    - something
- something else
```

Currently there's no way to accomplish this without manually counting the leading spaces, as it's not possible to detect the column where `<%=` appeared.



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

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [ruby-core:91106] [Ruby trunk Feature#15538] Erb indenting / unindenting trim mode
       [not found] <redmine.issue-15538.20190115133510@ruby-lang.org>
  2019-01-15 13:35 ` [ruby-core:91103] [Ruby trunk Feature#15538] Erb indenting / unindenting trim mode kimmo.lehto
  2019-01-15 14:10 ` [ruby-core:91105] " takashikkbn
@ 2019-01-15 15:22 ` merch-redmine
  2019-01-16  9:55 ` [ruby-core:91119] " kimmo.lehto
                   ` (9 subsequent siblings)
  12 siblings, 0 replies; 13+ messages in thread
From: merch-redmine @ 2019-01-15 15:22 UTC (permalink / raw)
  To: ruby-core

Issue #15538 has been updated by jeremyevans0 (Jeremy Evans).


kke (Kimmo Lehto) wrote:
> 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: '|')`

I think if we are going to add support for `<%|` and `<%|=` tags to ERB, it would be a better idea to use them to support output of captured blocks, as Erubi offers optional support for (https://github.com/jeremyevans/erubi#capturing).  This allows you to do things like:

~~~
<%|= form do %>
  <input>
<%| end %>
~~~

and have it output:

~~~
<form>
  <input>
</form>
~~~

assuming an appropriate definition of `form`.  This is basically what Rails does for normal `<%=` tags, but without attempting to parse ruby code with regexp (https://github.com/rails/rails/blob/5-2-stable/actionview/lib/action_view/template/handlers/erb/erubi.rb#L45-L61).

I'm not opposed to the idea of using a trim mode to modify indentation, but I think it should use a character other than `|` if support is added for it.

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

* 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 looks nice:

``` ruby
- horse
<% ['cat', 'dog', 'goldfish'].each do |pet| %>
  <% unless pet == 'goldfish' %>
    - <%= pet %>
  <% end %>
<% end %>
```

But unfortunately it will render with "extra" indentation:

```
- horse
   - cat
   - dog
```

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

```ruby
- horse
<%| ['cat', 'dog', 'goldfish'].each do |pet| %>
....
<% end %>
```

And it would output as desired without the "extra" indentation. Currently, to produce such output, you have write your erb template without indentation or using a jumpy mixed indentation (code and content have different indentation levels but are interleaved) and it's not a very user/editor friendly way to work.

## 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 = "- something\n- something else" %>
foo:
  bar: 
    <%|= bar_content %>
```

Which would produce something like:

```yaml
foo:
  bar:
    - something
    - something else
```

Instead of the invalid:

```yaml
foo:
  bar:
    - something
- something else
```

Currently there's no way to accomplish this without manually counting the leading spaces, as it's not possible to detect the column where `<%=` appeared.



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

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [ruby-core:91119] [Ruby trunk Feature#15538] Erb indenting / unindenting trim mode
       [not found] <redmine.issue-15538.20190115133510@ruby-lang.org>
                   ` (2 preceding siblings ...)
  2019-01-15 15:22 ` [ruby-core:91106] " merch-redmine
@ 2019-01-16  9:55 ` kimmo.lehto
  2019-01-16  9:58 ` [ruby-core:91120] " kimmo.lehto
                   ` (8 subsequent siblings)
  12 siblings, 0 replies; 13+ messages in thread
From: kimmo.lehto @ 2019-01-16  9:55 UTC (permalink / raw)
  To: ruby-core

Issue #15538 has been updated by kke (Kimmo Lehto).

Description updated

Clarified and added some examples


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

* 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/

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [ruby-core:91120] [Ruby trunk Feature#15538] Erb indenting / unindenting trim mode
       [not found] <redmine.issue-15538.20190115133510@ruby-lang.org>
                   ` (3 preceding siblings ...)
  2019-01-16  9:55 ` [ruby-core:91119] " kimmo.lehto
@ 2019-01-16  9:58 ` kimmo.lehto
  2019-01-16 12:27 ` [ruby-core:91124] " zn
                   ` (7 subsequent siblings)
  12 siblings, 0 replies; 13+ messages in thread
From: kimmo.lehto @ 2019-01-16  9:58 UTC (permalink / raw)
  To: ruby-core

Issue #15538 has been updated by kke (Kimmo Lehto).

Description updated

(missing closing parenthesis)

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

* 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/

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [ruby-core:91124] [Ruby trunk Feature#15538] Erb indenting / unindenting trim mode
       [not found] <redmine.issue-15538.20190115133510@ruby-lang.org>
                   ` (4 preceding siblings ...)
  2019-01-16  9:58 ` [ruby-core:91120] " kimmo.lehto
@ 2019-01-16 12:27 ` zn
  2019-01-16 12:55 ` [ruby-core:91125] " takashikkbn
                   ` (6 subsequent siblings)
  12 siblings, 0 replies; 13+ messages in thread
From: zn @ 2019-01-16 12:27 UTC (permalink / raw)
  To: ruby-core

Issue #15538 has been updated by znz (Kazuhiro NISHIYAMA).


How about following style?

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

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

* 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/

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [ruby-core:91125] [Ruby trunk Feature#15538] Erb indenting / unindenting trim mode
       [not found] <redmine.issue-15538.20190115133510@ruby-lang.org>
                   ` (5 preceding siblings ...)
  2019-01-16 12:27 ` [ruby-core:91124] " zn
@ 2019-01-16 12:55 ` takashikkbn
  2019-01-24 12:05 ` [ruby-core:91248] " kimmo.lehto
                   ` (5 subsequent siblings)
  12 siblings, 0 replies; 13+ messages in thread
From: takashikkbn @ 2019-01-16 12:55 UTC (permalink / raw)
  To: ruby-core

Issue #15538 has been updated by k0kubun (Takashi Kokubun).


Thanks for the update. You didn't answer 2 but I guess you're using `trim_mode: '-'` or something including "-". Note that your "extra indentation" result is still not valid one since it should have 4 spaces in the real world. Do not treat your example indentation as trivial while talking about the indentation feature.

Now I'm kind of understanding what you want to achieve. But the details of what you want is not 100% clear to me, and with a real implementation your first example does not seem to work as you intended. So, let me ask questions for each feature.

## <%|
For this,

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

* When does the *de-indentation* end?
  * When ERB finds the second `end` matching `each do`? If so, as it's super hard to implement (note that ERB is NOT aware of Ruby expressions inside "<%"s, so you should give up detecting the "matching" `end`), please consider changing the syntax to the following one like Erubi's capture syntax (by having second "<%|", ERB will be able to know when it should finish de-indentation):

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

* Assuming the above suggestion is accepted, what's the expected result of the following template?

```erb
- foo
  <%| ['bar', 'baz'].each do |text| -%>
    - <%= text %>
  <%| end -%>
```

maybe this 2 spaces, not 0 space or 4 spaces? (because the first "<%|" is indented with 2 spaces, any indentation longer than 2  is shrunk to 2 spaces until it reaches the second "<%|")

```erb
- foo
  - bar
  - bar
```

* What happens when non-space is in the same line before "<%|"? Can ERB raise an error for it?

```
  foo <%| 3.times do |i| %>
    <%= i %>
  <%| end %>
```

* Could you consider not using "<%|" for this since Erubi is using it for capturing as @jeremyevans said?

## <%|=
* Same here. Please consider using another tag literal.
* What happens if "<%=" is placed inside "<%|" area? Indentation the same as "<%|" + extra indentation for "<%="? Can we make it an error because it's too hard to expect the behavior?

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

* 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/

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [ruby-core:91248] [Ruby trunk Feature#15538] Erb indenting / unindenting trim mode
       [not found] <redmine.issue-15538.20190115133510@ruby-lang.org>
                   ` (6 preceding siblings ...)
  2019-01-16 12:55 ` [ruby-core:91125] " takashikkbn
@ 2019-01-24 12:05 ` kimmo.lehto
  2019-01-24 12:37 ` [ruby-core:91250] " takashikkbn
                   ` (4 subsequent siblings)
  12 siblings, 0 replies; 13+ messages in thread
From: kimmo.lehto @ 2019-01-24 12:05 UTC (permalink / raw)
  To: ruby-core

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/

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [ruby-core:91250] [Ruby trunk Feature#15538] Erb indenting / unindenting trim mode
       [not found] <redmine.issue-15538.20190115133510@ruby-lang.org>
                   ` (7 preceding siblings ...)
  2019-01-24 12:05 ` [ruby-core:91248] " kimmo.lehto
@ 2019-01-24 12:37 ` takashikkbn
  2019-02-08 12:50 ` [ruby-core:91492] " kimmo.lehto
                   ` (3 subsequent siblings)
  12 siblings, 0 replies; 13+ messages in thread
From: takashikkbn @ 2019-01-24 12:37 UTC (permalink / raw)
  To: ruby-core

Issue #15538 has been updated by k0kubun (Takashi Kokubun).


Most of "foo"-"bar" examples seem to be indented strangely. I guess you meant the following one for all like this ("f" and "b" start with the same column), right?

```
3: foo
   bar
```

Now, you introduced 4 different new tokens (do not assume "<%|-" is transparently supported when "<%|" is supported):

* `<|`
* `<|-`
* `<|=`
* `|>`

Thank you for providing real examples (it's nice), but also,

* Could you summarize the effect of each token? 
* I'm still not understanding why 4 new tokens are needed. Can you eliminate 1 or 2 from them?

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

* 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/

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [ruby-core:91492] [Ruby trunk Feature#15538] Erb indenting / unindenting trim mode
       [not found] <redmine.issue-15538.20190115133510@ruby-lang.org>
                   ` (8 preceding siblings ...)
  2019-01-24 12:37 ` [ruby-core:91250] " takashikkbn
@ 2019-02-08 12:50 ` kimmo.lehto
  2019-02-08 16:05 ` [ruby-core:91496] " takashikkbn
                   ` (2 subsequent siblings)
  12 siblings, 0 replies; 13+ messages in thread
From: kimmo.lehto @ 2019-02-08 12:50 UTC (permalink / raw)
  To: ruby-core

Issue #15538 has been updated by kke (Kimmo Lehto).

Description updated

Yes, it appears I made an indentation error in my foo-bar examples. The indentation of `bar` was supposed to be as deep as on `foo`.

I added a tag summary.


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

* 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
```

This would require these new tags:

1. `<%|` begin a capturing a block which will be reindented to the column of the `<` character
2. `|%>` end the capturing block
3. `<%|=` like regular `<%=` but multiline strings will be reindented to the column of the `<` character

Optionally versions of the block tags with whitespace trim control:

4. `<%-|` like `<%|` but if block outputs nothing, remove leading whitespace
5. `|-%>`like `|%>` but remove trailing whitespace and linefeed from the line this tag appears on




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

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [ruby-core:91496] [Ruby trunk Feature#15538] Erb indenting / unindenting trim mode
       [not found] <redmine.issue-15538.20190115133510@ruby-lang.org>
                   ` (9 preceding siblings ...)
  2019-02-08 12:50 ` [ruby-core:91492] " kimmo.lehto
@ 2019-02-08 16:05 ` takashikkbn
  2019-02-14  8:34 ` [ruby-core:91545] [Ruby trunk Feature#15538] Erb indenting / unindenting kimmo.lehto
  2019-02-14  9:17 ` [ruby-core:91546] " takashikkbn
  12 siblings, 0 replies; 13+ messages in thread
From: takashikkbn @ 2019-02-08 16:05 UTC (permalink / raw)
  To: ruby-core

Issue #15538 has been updated by k0kubun (Takashi Kokubun).

Status changed from Feedback to Third Party's Issue

Thank you for the update.

As @jeremyevans said, the tags conflict with ones already used by Erubi. While you explained `<%|` as "capturing a block", I think what your `<%|` does in your examples seems to behave differently from Erubi's capture.

As your `<%|` is conflicting with a widely-used ERB-like gem Erubi, I don't think it's a good idea to introduce your suggestion as `<%|`. But you preferred `<%|` even after I said "Could you consider not using `<%|`". If we really need it, I think that should be achieved as an unofficial gem so that we do not break existing ecosystem globally.

So I prepared this for you https://github.com/k0kubun/erb-indent. Since your specification does not make a full sense to me, I did not implement full features of your suggestion. For example, why would we need `|%>` for the `<%|=` line? Only you can understand such kind of details, so please complete the implementation by yourself. It's already demonstrating how we could implement extra tag like `<%|` and only details of `<%|` features are missing. Thank you.

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

* Author: kke (Kimmo Lehto)
* Status: Third Party's Issue
* 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
```

This would require these new tags:

1. `<%|` begin a capturing a block which will be reindented to the column of the `<` character
2. `|%>` end the capturing block
3. `<%|=` like regular `<%=` but multiline strings will be reindented to the column of the `<` character

Optionally versions of the block tags with whitespace trim control:

4. `<%-|` like `<%|` but if block outputs nothing, remove leading whitespace
5. `|-%>`like `|%>` but remove trailing whitespace and linefeed from the line this tag appears on




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

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [ruby-core:91545] [Ruby trunk Feature#15538] Erb indenting / unindenting
       [not found] <redmine.issue-15538.20190115133510@ruby-lang.org>
                   ` (10 preceding siblings ...)
  2019-02-08 16:05 ` [ruby-core:91496] " takashikkbn
@ 2019-02-14  8:34 ` kimmo.lehto
  2019-02-14  9:17 ` [ruby-core:91546] " takashikkbn
  12 siblings, 0 replies; 13+ messages in thread
From: kimmo.lehto @ 2019-02-14  8:34 UTC (permalink / raw)
  To: ruby-core

Issue #15538 has been updated by kke (Kimmo Lehto).

Description updated
Subject changed from Erb indenting / unindenting trim mode to Erb indenting / unindenting 

Perhaps `<%~` would be good as it resembles the squiggly heredoc `<<~EOB`

I'll try to improve on your PoC.

It seems to only work when the `<%|` is in the beginning of the line, for anything else it fails. I have yet to find a way to find the index of `stag`, but I have a hunch it has to be done in the line scanner and yielded there.

Also, something like this should work:

```
<%= "abcd" %> <%~ [1.2.3].each do |num| -%>
                <%= num %>
              <%~ end -%>
```

which would produce:

```
abcd 1
     2
     3
 ```


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

* Author: kke (Kimmo Lehto)
* Status: Third Party's Issue
* Priority: Normal
* Assignee: 
* Target version: 
----------------------------------------
In `Erb`, would it be possible to add a new tag that would indent the following content to match the depth of the tag? The tag could be `<%~` (to resemble the `<<~EOS` squiggy heredoc).

## 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 `<%~` 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
```

Another example:

```
<%= "abcd" %> <%~ [1.2.3].each do |num| -%>
                <%= num %>
              <%~ end -%>
```

would produce:

```
abcd 1
     2
     3
 ```


## Using with `=`

It would also be handy if the `~` could be used in `<%=` statements, perhaps as `<%~=`. This would be excellent for example when templating YAML's:

```yaml
<%- bars = %w(abc def)" -%>
foo:
  bar: 
    <%~= bars.map { |bar| "- #{bar}\n" } %>
```

Which would reindent the statement outcome to produce something like:

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

This would require these new tags:

1. `<%~` begin a code block and begin or end reindentation mode. content produced inside the block will be reindented to the depth of the `<` character in `<%~`. If the indentation mode was already active due to a previous `<%~`, it ends the indentation mode.
2. `<%~=` like regular `<%=` but multiline strings will be reindented to the column of the `<` character





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

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [ruby-core:91546] [Ruby trunk Feature#15538] Erb indenting / unindenting
       [not found] <redmine.issue-15538.20190115133510@ruby-lang.org>
                   ` (11 preceding siblings ...)
  2019-02-14  8:34 ` [ruby-core:91545] [Ruby trunk Feature#15538] Erb indenting / unindenting kimmo.lehto
@ 2019-02-14  9:17 ` takashikkbn
  12 siblings, 0 replies; 13+ messages in thread
From: takashikkbn @ 2019-02-14  9:17 UTC (permalink / raw)
  To: ruby-core

Issue #15538 has been updated by k0kubun (Takashi Kokubun).


> Perhaps <%~ would be good as it resembles the squiggly heredoc <<~EOB

Thanks to rethink that part. I feel it's a good idea to make it similar to `<<~`.

The proposal change makes your idea closer to be added to the ERB core, but we still need working code from you because the behaviors on full edge cases are hard to understand from the given examples. Let's try implementing that in erb-indent.gem (or a gem forked from it if you like) first so that we can try/use the feature without waiting for agreements and Ruby releases.

> It seems to only work when the <%| is in the beginning of the line, for anything else it fails. I have yet to find a way to find the index of stag, but I have a hunch it has to be done in the line scanner and yielded there.

Try override #make_scanner (and return a scanner inherited from existing one) if you need to change the scanner's behavior, like I did in #make_compiler.

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

* Author: kke (Kimmo Lehto)
* Status: Third Party's Issue
* Priority: Normal
* Assignee: 
* Target version: 
----------------------------------------
In `Erb`, would it be possible to add a new tag that would indent the following content to match the depth of the tag? The tag could be `<%~` (to resemble the `<<~EOS` squiggy heredoc).

## 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 `<%~` 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
```

Another example:

```
<%= "abcd" %> <%~ [1.2.3].each do |num| -%>
                <%= num %>
              <%~ end -%>
```

would produce:

```
abcd 1
     2
     3
 ```


## Using with `=`

It would also be handy if the `~` could be used in `<%=` statements, perhaps as `<%~=`. This would be excellent for example when templating YAML's:

```yaml
<%- bars = %w(abc def)" -%>
foo:
  bar: 
    <%~= bars.map { |bar| "- #{bar}\n" } %>
```

Which would reindent the statement outcome to produce something like:

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

This would require these new tags:

1. `<%~` begin a code block and begin or end reindentation mode. content produced inside the block will be reindented to the depth of the `<` character in `<%~`. If the indentation mode was already active due to a previous `<%~`, it ends the indentation mode.
2. `<%~=` like regular `<%=` but multiline strings will be reindented to the column of the `<` character





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

^ permalink raw reply	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2019-02-14  9:17 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <redmine.issue-15538.20190115133510@ruby-lang.org>
2019-01-15 13:35 ` [ruby-core:91103] [Ruby trunk Feature#15538] Erb indenting / unindenting trim mode kimmo.lehto
2019-01-15 14:10 ` [ruby-core:91105] " takashikkbn
2019-01-15 15:22 ` [ruby-core:91106] " merch-redmine
2019-01-16  9:55 ` [ruby-core:91119] " kimmo.lehto
2019-01-16  9:58 ` [ruby-core:91120] " kimmo.lehto
2019-01-16 12:27 ` [ruby-core:91124] " zn
2019-01-16 12:55 ` [ruby-core:91125] " takashikkbn
2019-01-24 12:05 ` [ruby-core:91248] " kimmo.lehto
2019-01-24 12:37 ` [ruby-core:91250] " takashikkbn
2019-02-08 12:50 ` [ruby-core:91492] " kimmo.lehto
2019-02-08 16:05 ` [ruby-core:91496] " takashikkbn
2019-02-14  8:34 ` [ruby-core:91545] [Ruby trunk Feature#15538] Erb indenting / unindenting kimmo.lehto
2019-02-14  9:17 ` [ruby-core:91546] " takashikkbn

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).