2553

I have a very long string:

Key: 'this is my very very very very very very long string'

I would like to express it over multiple shorter lines, e.g.,

Key: 'this is my very very very ' +
     'long string'

I would like to use quotes as above, so that I don't need to escape anything within the string.

Mateen Ulhaq
  • 24,552
  • 19
  • 101
  • 135
jjkparker
  • 27,597
  • 6
  • 28
  • 29
  • 4
    Quick tip: you **cannot place comment inside scalar**, so you cannot comment part of multiline key or value. Have to move required lines out of declaration. https://stackoverflow.com/questions/20890445/yaml-comments-in-multi-line-strings – gavenkoa Jun 30 '21 at 08:31
  • Use this reference: https://yaml-multiline.info/ – Ed Randall May 04 '22 at 10:17

9 Answers9

5613

There are 5 6 NINE (or 63*, depending how you count) different ways to write multi-line strings in YAML.

TL;DR

  • Use > most of the time: interior line breaks are stripped out, although you get one at the end:

      key: >
        Your long
        string here.
    
  • Use | if you want those linebreaks to be preserved as \n (for instance, embedded markdown with paragraphs).

      key: |
        ### Heading
    
        * Bullet
        * Points
    
  • Use >- or |- instead if you don't want a linebreak appended at the end.

  • Use "..." if you need to split lines in the middle of words or want to literally type linebreaks as \n:

      key: "Antidisestab\
       lishmentarianism.\n\nGet on it."
    
  • YAML is crazy.

Block scalar styles (>, |)

These allow characters such as \ and " without escaping, and add a new line (\n) to the end of your string.

> Folded style removes single newlines within the string (but adds one at the end, and converts double newlines to singles):

Key: >
  this is my very very very
  long string

this is my very very very long string\n

Extra leading space is retained and causes extra newlines. See note below.

Advice: Use this. Usually this is what you want.

| Literal style turns every newline within the string into a literal newline, and adds one at the end:

Key: |
  this is my very very very 
  long string

this is my very very very\nlong string\n

Here's the official definition from the YAML Spec 1.2

Scalar content can be written in block notation, using a literal style (indicated by “|”) where all line breaks are significant. Alternatively, they can be written with the folded style (denoted by “>”) where each line break is folded to a space unless it ends an empty or a more-indented line.

Advice: Use this for inserting formatted text (especially Markdown) as a value.

Block styles with block chomping indicator (>-, |-, >+, |+)

You can control the handling of the final new line in the string, and any trailing blank lines (\n\n) by adding a block chomping indicator character:

  • >, |: "clip": keep the line feed, remove the trailing blank lines.
  • >-, |-: "strip": remove the line feed, remove the trailing blank lines.
  • >+, |+: "keep": keep the line feed, keep trailing blank lines.

"Flow" scalar styles ( , ", ')

These have limited escaping, and construct a single-line string with no new line characters. They can begin on the same line as the key, or with additional newlines first, which are stripped. Doubled newline characters become one newline.

plain style (no escaping, no # or : combinations, first character can't be ", ' or many other punctuation characters ):

Key: this is my very very very 
  long string

Advice: Avoid. May look convenient, but you're liable to shoot yourself in the foot by accidentally using forbidden punctuation and triggering a syntax error.

double-quoted style (\ and " must be escaped by \, newlines can be inserted with a literal \n sequence, lines can be concatenated without spaces with trailing \):

Key: "this is my very very \"very\" loooo\
  ng string.\n\nLove, YAML."

"this is my very very \"very\" loooong string.\n\nLove, YAML."

Advice: Use in very specific situations. This is the only way you can break a very long token (like a URL) across lines without adding spaces. And maybe adding newlines mid-line is conceivably useful.

single-quoted style (literal ' must be doubled, no special characters, possibly useful for expressing strings starting with double quotes):

Key: 'this is my very very "very"
  long string, isn''t it.'

"this is my very very \"very\" long string, isn't it."

Advice: Avoid. Very few benefits, mostly inconvenience.

Block styles with indentation indicators

Just in case the above isn't enough for you, you can add a "block indentation indicator" (after your block chomping indicator, if you have one):

- >8
        My long string
        starts over here
- |+1
 This one
 starts here

Note: Leading spaces in Folded style (>)

If you insert extra spaces at the start of not-the-first lines in Folded style, they will be kept, with a bonus newline. (This doesn't happen with flow styles.) Section 6.5:

In addition, folding does not apply to line breaks surrounding text lines that contain leading white space. Note that such a more-indented line may consist only of such leading white space.

- >
    my long
      string
                    
    many spaces above
- my long
      string
                    
    many spaces above
    

["my long\n string\n \nmany spaces above\n","my long string\nmany spaces above"]

Summary

In this table, _ means space character. \n means "newline character" (\n in JavaScript) except under "Other features". "Leading space" applies after the first line (which establishes the indent)

> | " ' >- >+ |- |+
Spaces/newlines converted as:
Trailing space → _ _ _ _ _ _
Leading space → \n_ \n_ \n_ \n_ \n_ \n_
Single newline → _ \n _ _ _ _ _ \n \n
Double newline → \n \n\n \n \n \n \n \n \n\n \n\n
Final newline → \n \n \n \n
Final double newline → \n\n \n\n
How to create a literal:
Single quote ' ' ' ' '' ' ' ' '
Double quote " " " \" " " " " "
Backslash \ \ \ \\ \ \ \ \ \
Other features
In-line newlines with \n
Spaceless newlines with \
# or : in value
Can start on same
line as key

Examples

Note the trailing spaces on the line before "spaces."

- >
  very "long"
  'string' with

  paragraph gap, \n and        
  spaces.
- | 
  very "long"
  'string' with

  paragraph gap, \n and        
  spaces.
- very "long"
  'string' with

  paragraph gap, \n and        
  spaces.
- "very \"long\"
  'string' with

  paragraph gap, \n and        
  s\
  p\
  a\
  c\
  e\
  s."
- 'very "long"
  ''string'' with

  paragraph gap, \n and        
  spaces.'
- >- 
  very "long"
  'string' with

  paragraph gap, \n and        
  spaces.

[
  "very \"long\" 'string' with\nparagraph gap, \\n and         spaces.\n", 
  "very \"long\"\n'string' with\n\nparagraph gap, \\n and        \nspaces.\n", 
  "very \"long\" 'string' with\nparagraph gap, \\n and spaces.", 
  "very \"long\" 'string' with\nparagraph gap, \n and spaces.", 
  "very \"long\" 'string' with\nparagraph gap, \\n and spaces.", 
  "very \"long\" 'string' with\nparagraph gap, \\n and         spaces."
]

*2 block styles, each with 2 possible block chomping indicators (or none), and with 9 possible indentation indicators (or none), 1 plain style and 2 quoted styles: 2 x (2 + 1) x (9 + 1) + 1 + 2 = 63

Some of this information has also been summarised here.

Grisha Levit
  • 8,194
  • 2
  • 38
  • 53
Steve Bennett
  • 114,604
  • 39
  • 168
  • 219
  • 1
    There are even more options when you look at the block chomping indicator. `|2+` will preserve whitespaces at the beginning of the line which exceed 2 whitespaces. – udondan Mar 15 '16 at 07:38
  • 1
    Note that apparently not all YAML parsers implement this completely. We use Jackson (2.5.3) in Java and `>-` does not remove all the newlines. We switched to a "plain style" overflow and that does what we need. – Robert Jack Will Mar 31 '16 at 13:02
  • 82
    Among the 63 syntaxes, do you think there is a single one that allows you to spell in multiple lines a string that should not have newlines nor spaces? I mean what one would write as `"..." + "..."` in most programming languages, or backslash before newline in Bash. – Tobia Jul 28 '16 at 15:33
  • 41
    @pepoluan I tried every possible combination and found only one that allows for spaceless concatenation: put double quotes around the string and a backslash before newline (and indentation.) Example: data:text/plain;base64,dGVzdDogImZvb1wKICBiYXIiCg== – Tobia Aug 26 '16 at 08:56
  • `pyyaml` appears to preserve newlines on `>` style strings :\ I ended up escaping the newlines with backslashes – ThorSummoner May 02 '17 at 00:07
  • 7
    This is ultimately the most bestests format for organizing structured data I've ever seen! What I think this answer is sorely missing though is the list of YAML parser implementations and what features they support. In my experience, most don't support chomping indicators at all, but the way they will handle them is different. – wvxvw Jan 18 '18 at 08:56
  • 123
    @wvxvw on the contrary, I think YAML is the worst format for many common use-cases (e.g., config files), not least because most people are drawn in by its apparent simplicity only to realize much later that it's an extremely complex format. YAML makes wrong things _look_ right - for example, an innocuous colon `:` within one string in a string array makes YAML interpret it as an array of objects. It violates the [principle of least astonishment](https://en.wikipedia.org/wiki/Principle_of_least_astonishment). – Vicky Chijwani Jan 31 '18 at 14:48
  • 12
    @VickyChijwani We are lost in translation. My comment was sarcastic, but sarcasm doesn't translate well. I very much agree with you. – wvxvw Jan 31 '18 at 15:52
  • 3
    @wvxvw sorry, yes, I too find that it's tricky to convey sarcasm in writing. Especially in a case like this because I know people who really _do_ think YAML is a great format :). Cheers! – Vicky Chijwani Jan 31 '18 at 19:51
  • "These allow escaping" Block Scalars don't allow escape sequences. Only double quotes support it. – tinita Feb 26 '18 at 18:11
  • 149
    Yet Another Multi Line string syntax – xdhmoore Aug 07 '18 at 21:29
  • 5
    @Tobia Can you please give an example for the "spaceless concatenation"? I am not able to grok `Example: data:text/plain;base64,dGVzdDogImZvb1wKICBiYXIiCg==` – jeffreyveon Sep 06 '18 at 11:53
  • 8
    @jeffreyveon That's just a way to share a literal snippet of text through the comment system's limitations. It's a data URI, you just paste into the browser's address bar. – Tobia Sep 12 '18 at 10:35
  • 1
    If you use `>1` or `|1`, then *some* of the indentation will be kept. For instance if the `>` is in the 3rd column (indented two spaces) then X-3 characters of indentation will be kept. – Steve Bennett Mar 29 '19 at 10:49
  • 52
    I always struggled to remember which one of '|' or '>' keeps or removes the line feeds. At some point I realized that, if read from left to right, the operators tell you how they transform the string. '|' has the same height on both sides meaning that the string will also stay the same height; while '>' is smaller on the right than on the left, meaning it will "compress" the string from many to just one line. Just wanted to leave that mnemonic here for those who haven't discovered it yet. – swenzel Jun 21 '19 at 08:55
  • @VickyChijwani ignoring opinions and views on YAML itself, observing **POLA** is arguably less sustainable the smaller the scale of the individual user interface elements (which, for YAML, consists of individual characters). There are only so many ways individual characters can be specified to represent both commands *and* data, and still avoid excess verbosity, "delimiter collision", and "leaning toothpick syndrome" (among other things). – dreftymac Jun 10 '21 at 15:41
  • For anyone struggling in remembering the different ways to use YAML multiline strings, you can find here (https://github.com/paolodenti/yaml-multiline) a simple test docker image, showing the different results with different syntaxes (in `docker-compose.yaml`). Just clone and `docker compose up --build` – pdenti Oct 13 '21 at 20:38
  • 1
    Or, um, just use https://yaml-online-parser.appspot.com/ – Steve Bennett Oct 14 '21 at 22:12
  • 1
    "Use `"..."` if you need to split lines in the middle of words or want to literally type linebreaks as `\n`" <— I'm confused by the ellipses. Shouldn't that be a backslash, given the example? "Use `"\"` if you need to split lines in the middle of words". Or am I missing something? – M. Justin Mar 10 '22 at 22:01
  • I sort of get what you mean, but I think the example makes it pretty clear how you use it. The ellipsis isn't literal - it's saying, use double quotes around a string if you have any of the following two needs. – Steve Bennett Mar 10 '22 at 23:37
  • 1
    YAML spec goal #7: "YAML should be easy to implement and use." So much for easy implementation... – Vadim Hagedorn Aug 12 '22 at 04:41
  • 4
    I keep coming back to this answer, and the number increases every time. – Dragas Jan 12 '23 at 18:49
  • We need Yet Another YAML Language – Emile Cormier Jun 19 '23 at 01:59
1424

Using yaml folded style. The indention in each line will be ignored. A line break will be inserted at the end.

Key: >
  This is a very long sentence
  that spans several lines in the YAML
  but which will be rendered as a string
  with only a single carriage return appended to the end.

http://symfony.com/doc/current/components/yaml/yaml_format.html

You can use the "block chomping indicator" to eliminate the trailing line break, as follows:

Key: >-
  This is a very long sentence
  that spans several lines in the YAML
  but which will be rendered as a string
  with NO carriage returns.

In either case, each line break is replaced by a space.

There are other control tools available as well (for controlling indentation for example).

See https://yaml-multiline.info/

Gabriel Staples
  • 36,492
  • 15
  • 194
  • 265
Matt Williamson
  • 39,165
  • 10
  • 64
  • 72
  • 1
    Thanks, but you can't wrap this syntax in quotes, it seems: the quotes appear as literals in the resulting string. – jjkparker Sep 27 '10 at 16:55
  • Somehow a carriage return is added right after the end of the translation in my app. That way Javascript sees it as multiple lines and fails. `{{- 'key'|trans -}}` does not work either. – Rvanlaak May 06 '15 at 14:48
  • In my experience, this syntax appends a `\n` at the end of the string. This may or may not be what you are looking for. – Rich Remer Mar 22 '18 at 00:41
  • 12
    _each line break is replaced by a space_ <-- but a double-line-break will be a line break. – Jean Jordaan Aug 05 '18 at 10:57
  • 1
    @Rvanlaak and @rich-remer Use the block chomper to avoid the newline at the end: `>-` – DylanYoung Nov 27 '18 at 15:46
  • I attempted some edits to reduce ambiguity, but then realized the ambiguity is too great for me to be certain I am making the right edits, so I rolled back my edits. Please look at my edits and help fix them to reduce ambiguity. Are the line breaks at the end of each line, the whole string, in the lines? I don't understand. Thanks. – Gabriel Staples Nov 18 '20 at 23:52
  • And all these `>-` and `|-` won't help you pass URL like `blabla.com/search.php?keywords="bla bla"` or command line string like `-A "111 222" -B "333 444"` as is without double quotes suppressing. Suprisingly yaml is not for programmers to store URLs and command lines as is `:-[ ]` – Andry Nov 25 '21 at 14:00
  • I found the provided link https://yaml-multiline.info useful. – anre Jan 21 '22 at 11:27
225

To preserve newlines use |, for example:

|
  This is a very long sentence
  that spans several lines in the YAML
  but which will be rendered as a string
  with newlines preserved.

is translated to "This is a very long sentence‌\n that spans several lines in the YAML‌\n but which will be rendered as a string‌\n with newlines preserved.\n"

Anthon
  • 69,918
  • 32
  • 186
  • 246
Ali Shakiba
  • 20,549
  • 18
  • 61
  • 88
  • This seems to work fine for me with two lines but not with three? – cboettig Oct 23 '13 at 22:09
  • Thanks, works fine there just like you say. For some reason in Pandoc's yaml headers I need to repeat the `|` on each line, for reasons that are not obvious to me: https://groups.google.com/forum/#!topic/pandoc-discuss/xuqEmhWgf9A – cboettig Oct 24 '13 at 19:48
  • Isn't an issue the fact that if I write: - field1: | one two - field1: | three for' I get: one\ntwo\n and three\nfor? I would aspect the \n after 2 to do not be there... – Alain1405 Jan 14 '14 at 16:52
  • When using multiline `cat` with delimiter this causes leading spaces (which are necessary for YAML) to be added to output. – Kalle Richter Apr 30 '16 at 14:27
  • @Rubytastic to have those break lines also in your HTML page generated by Rails, you need some precautions. I already answered here: http://stackoverflow.com/questions/10982706/how-to-break-lines-in-yml-localization-files-on-rails#answer-39658561 – Diego D Sep 23 '16 at 10:45
  • @KarlRichter I'm running into this, the first line is okay, however all subsequent lines have a trailing space that causes elasticsearch to reject the whole config – Jonathan Sep 12 '17 at 08:49
  • `echo -e $CONFIG | awk '{$1=$1};1'` will remove trailing and leading spaces – Jonathan Sep 12 '17 at 09:01
  • @AliShakiba You missed the final newline in the translation. And it is also not necessary to indent the lines of the scalar if it is at the root of document. – Anthon Nov 09 '18 at 16:38
152

1. Block Notation(plain, flow-style, scalar): Newlines become spaces and extra newlines after the block are removed

---
# Note: It has 1 new line after the string
content:
    Arbitrary free text
    over multiple lines stopping
    after indentation changes...

...

Equivalent JSON

{
 "content": "Arbitrary free text over multiple lines stopping after indentation changes..."
}

2. Literal Block Scalar: A Literal Block Scalar | will include the newlines and any trailing spaces. but removes extra

newlines after the block.

---
# After string we have 2 spaces and 2 new lines
content1: |
 Arbitrary free text
 over "multiple lines" stopping
 after indentation changes...  


...

Equivalent JSON

{
 "content1": "Arbitrary free text\nover \"multiple lines\" stopping\nafter indentation changes...  \n"
}

3. + indicator with Literal Block Scalar: keep extra newlines after block

---
# After string we have 2 new lines
plain: |+
 This unquoted scalar
 spans many lines.


...

Equivalent JSON

{
 "plain": "This unquoted scalar\nspans many lines.\n\n\n"
}

4. – indicator with Literal Block Scalar: means that the newline at the end of the string is removed.

---
# After string we have 2 new lines
plain: |-
 This unquoted scalar
 spans many lines.


...

Equivalent JSON

{
 "plain": "This unquoted scalar\nspans many lines."
}

5. Folded Block Scalar(>):

will fold newlines to spaces and but removes extra newlines after the block.

---
folded_newlines: >
 this is really a
 single line of text
 despite appearances


...

Equivalent JSON

{
 "fold_newlines": "this is really a single line of text despite appearances\n"
}

for more you can visit my Blog

Arayan Singh
  • 3,192
  • 3
  • 16
  • 35
  • Did you intend for example #4 to use "|-" after the colon? Also, you can lose the "---" directives end markers here, as you're only showing one document. The document end markers are helpful to highlight the trailing whitespace in the documents. Apart from that, though, there's no need for explicit documents. – seh Apr 06 '18 at 13:43
  • thanks for pointing out. that was a typo. A have fixed that. I have provided starting and ending marker so that everyone can see new lines after the string. – Arayan Singh Apr 06 '18 at 14:17
  • Nr.1 is described as a plain, flow-style, scalar in the YAML specification. Calling it block-style is misleading. – Anthon Nov 09 '18 at 16:47
  • Changes Nr.1 as a plain, flow-style, scalar. – Arayan Singh Feb 13 '20 at 09:10
  • This site can’t be reached. Check if there is a typo in interviewbubble.com. DNS_PROBE_FINISHED_NXDOMAIN. Thanks. – ssi-anik Apr 22 '22 at 10:39
76

To concatenate long lines without whitespace, use double quotes and escape the newlines with backslashes:

key: "Loremipsumdolorsitamet,consecteturadipiscingelit,seddoeiusmodtemp\
  orincididuntutlaboreetdoloremagnaaliqua."
phs
  • 10,687
  • 4
  • 58
  • 84
  • 1
    Thanks, this really helped me to define Docker volumes over multiple lines! If someone has the same problem, [here is my solution on an Online YAML Parser](https://yaml-online-parser.appspot.com/?yaml=version%3A+%272%27%0Aservices%3A%0A++app%3A%0A++++image%3A+mikemitterer%2Fembedded_server%0A%0A++++command%3A+--serve+%0A%0A++++ports%3A%0A++++++-+%228080%3A8080%22%0A%0A++++volumes%3A%0A++++++-+%0A++++++++%22%2Fcerts%2Fstart.properties%3A%5C%0A+++++++++++%2Fusr%2Flocal%2Fshare%2Fjava%2Fembedded_server%2Fetc%2Fstart.properties%22%0A%0A&type=json) – Mike Mitterer Aug 03 '17 at 10:05
  • Ah finally. I was trying to wrap long ssh-keys in Puppet's Hiera yaml files over multiple lines but always got unwanted spaces until I used your answer. Thanks. – Martijn Heemels Nov 30 '17 at 09:53
  • I am looking for this answer. This is silly there is no option in yaml to do something easy in this approach. – ikhvjs May 09 '22 at 08:56
50

You might not believe it, but YAML can do multi-line keys too:

?
 >
 multi
 line
 key
:
  value
Mohsen
  • 64,437
  • 34
  • 159
  • 186
  • 7
    Explanation needed (what is "?"). – ilyaigpetrov Sep 26 '17 at 11:38
  • @ilyaigpetrov exactly as written, "multi-line" key. Usually you do things like `key:value`, but if your key contains new-line, you can do it as described above – goFrendiAsgard Oct 09 '17 at 01:33
  • 8
    Any example of a real-world use-case for this? – Richard-Degenne Dec 11 '17 at 14:49
  • 4
    @ilyaigpetrov the `?` is the key indicator (as in key in a mapping). In many situations you may leave out the key indicator, when the (required) value indicator `:` after the key makes parsing unambiguous. But that is not the case, you'll have to use this to explicitly mark the key. – Anthon Nov 09 '18 at 16:51
22

In case you're using YAML and Twig for translations in Symfony, and want to use multi-line translations in Javascript, a carriage return is added right after the translation. So even the following code:

var javascriptVariable = "{{- 'key'|trans -}}";

Which has the following yml translation:

key: >
    This is a
    multi line 
    translation.

Will still result into the following code in html:

var javascriptVariable = "This is a multi line translation.
";

So, the minus sign in Twig does not solve this. The solution is to add this minus sign after the greater than sign in yml:

key: >-
    This is a
    multi line 
    translation.

Will have the proper result, multi line translation on one line in Twig:

var javascriptVariable = "This is a multi line translation.";
Anthon
  • 69,918
  • 32
  • 186
  • 246
Rvanlaak
  • 2,971
  • 20
  • 40
11

For situations were the string might contain spaces or not, I prefer double quotes and line continuation with backslashes:

key: "String \
  with long c\
  ontent"

But note about the pitfall for the case that a continuation line begins with a space, it needs to be escaped (because it will be stripped away elsewhere):

key: "String\
  \ with lon\
  g content"

If the string contains line breaks, this needs to be written in C style \n.

See also this question.

Joe
  • 3,090
  • 6
  • 37
  • 55
  • If it is stripped away **elsewhere**, i.e. not in that position, can you update your answer with information about **where** it will be stripped away. Please also write which parser (for which language) does that? I have only seen parsers strip such leading/trailing spaces in multiline quotes strings **in place**. – Anthon Nov 09 '18 at 16:54
-4

None of the above solutions worked for me, in a YAML file within a Jekyll project. After trying many options, I realized that an HTML injection with <br> might do as well, since in the end everything is rendered to HTML:

name: | In a village of La Mancha <br> whose name I don't <br> want to remember.

At least it works for me. No idea on the problems associated to this approach.

Irene
  • 579
  • 2
  • 10
  • 19
  • 6
    Your solution refers to a different problem: in your case you want linebreaks to appear in rendered HTML as result of processing YAML. HTML and YAML don't have an implicit relationship with each other. And even if YAML would pass regular linebreaks HTML would ignore them. Eventually the op's question is related to using linebreaks in YAML itself just to prevent very long lines. It doesn't care about how the data might be rendered in the end. Why telling this? Because this explains why all the other solutions given here don't work in your case. – Thomas Urban May 22 '19 at 18:48