George Shuklin
George Shuklin

Reputation: 7877

How to fold multiline yaml string with identations

(before providing an answer, mind that I've tried both > and >- with no success).

I'm trying to be fancy in ansible variables. I want to have a well-formated SQL (pseudo-sql) query to be folded into line without new line characters.

My problem is that > operator does not work if string have identations...

---
- hosts: localhost
  gather_facts: no
  tasks:
   - debug: var=foo
  vars:
   foo: >
     select foo
       from bar
       where ok
     join left
       select baz
       from boo

Produces:

ok: [localhost] => { "foo": "select foo\n from bar\n where ok\njoin left\n select baz\n from boo\n \n" }

And I don't want to see \n in the middle of the text. Can this be solved with YAML powers alone?

Upvotes: 3

Views: 1891

Answers (2)

Anthon
Anthon

Reputation: 76599

The reason you get newlines in your data loaded from YAML is that according to the YAML specification:

Folding allows long lines to be broken anywhere a single space character separates two non-space characters.

And since there are spaces before from bar, the newline on the line before cannot have been on a "fold" and is a hard newline.

To "solve" this with YAML alone you can try to use the plain style scalars as @flyx already indicated, but be aware that there are several restrictions on plain scalars that don't apply for folded scalars. Those might not apply to your example, but probably do when you have real SQL syntax there.

The other thing you could do is not indent after the folds:

foo: >
  select foo
  from bar
  where ok
  join left
  select baz
  from boo

which doesn't really make things more readable, but doesn't have the restrictions that plain style scalars have.

The best solution, while keeping things maximum readable would be to add a tag and use literal style scalar

foo: !flatten |
  select foo
    from bar
    where ok
  join left
    select baz
    from boo

and make the object loaded for the tag !flatten, unfold the following lines appropriately during loading (i.e. replace newline followed by spaces by a single newline).

Although using a tag is IMO the best solution, that is stretching the term "by YAML alone" beyond what is reasonable.

Upvotes: 2

flyx
flyx

Reputation: 39678

Yeah, that's the strangest „feature“ YAML has. Use plain multi-line scalars instead:

---
- hosts: localhost
  gather_facts: no
  tasks:
   - debug: var=foo
  vars:
   foo:
     select foo
       from bar
       where ok
     join left
       select baz
       from boo

Upvotes: 2

Related Questions