YAML file syntax - syntax

I'm working with a yaml file that I'm not supposed to break it. The problem is I'm not familiar with it, so is not sure if I can change some of its format...
The source file we received looks like this:
- items:
- heading: Maps
description: >
Integrate 3D buildings and tacos.
image_path: /music/images/v2/web_api-music.png
After processing the files, it looks like this:
- items:
- heading: Maps
description: > Integrate 3D buildings and tacos.
image_path: /music/images/v2/web_api-music.png
Does it break the code if the line break is missing between the greater than sign and the string? Would it have any potential impact on the UI format?
Also does it matter if there's extra spaces before "Integrate 3D buildings and tacos"? like below
- items:
- heading: Maps
description: >
Integrate 3D buildings and tacos.
image_path: /music/images/v2/web_api-music.png
Thank you and happy Thanksgiving!

It is easiest to check your files using some online YAML validator. For example: yamllint. Also, there are libraries for many languages, so if possible I recommend you use one of these to process your yaml files.
Your first processes file is not valid. There should be a newline after the >, or you can leave out the >.
Your last example is valid. The amount of indentation doesn't matter. From the spec:
The amount of indentation is a presentation detail and must not be used to convey content information.
[...]
Each node must be indented further than its parent node. All sibling nodes must use the exact same indentation level. However the content of each sibling node may be further indented independently.

See the spec for the version of yaml you are interested in
Generally speaking, the > is only significant at the end of the line, and means that the subsequent indented block should be folded on to this line with all newlines and leading/trailing space removed (replaced by sinlge spaces.) So
- heading: Maps
description: >
Integrate 3D buildings and tacos.
image_path: /music/images/v2/web_api-music.png
would be equivalent to
- heading: Maps
description: Integrate 3D buildings and tacos.
and leaving the > in when you remove the newline essentially adds it to the string value.
Changing the amount of indentation of any given block is generally irrelevant, as long as the lines of a block are consistently indented

Related

Why isn't two-spaced YAML parsed like four-spaced YAML?

I'm seeing strange behavior when parsing YAML (using Ruby 2.5/Psych) created using two space indentations. The same file, indented with four spaces per line works -- to my mind -- as expected.
Two spaces:
windows:
- shell:
panes:
- echo hello
results in the following hash:
{"windows"=>[{"shell"=>nil, "panes"=>["echo hello"]}]}
Whereas using four space indentations:
windows:
- shell:
panes:
- echo hello
results in:
{"windows"=>[{"shell"=>{"panes"=>["echo hello"]}}]}
I just skimmed through the spec and didn't see anything relevant to this issue.
Is this behavior expected? If so, I'd greatly appreciate links to resources explaining why.
While Wayne's solution is correct, the explanation seems a bit off, so I'll throw in mine:
In YAML, the - for block sequence items (like ? and : for block mappings) is treated as indentation (spec):
The “-”, “?” and “:” characters used to denote block collection entries are perceived by people to be part of the indentation. This is handled on a case-by-case basis by the relevant productions.
Moreover, all block collections (sequences and mappings) take their indentation from their first item (since there is no explicit starting indicator). So in the line - shell:, the - defines the indentation level of the newly started sequence, while at the same time, shell: defines the indentation level of the newly started mapping, which is the content of the sequence item. Note how the - is treated as indentation for defining the indentation level of the mapping.
Now, revisiting your first example:
windows:
- shell:
panes:
- echo hello
panes: is on the same level as shell:. This means that YAML parses it as key of the mapping started by shell:, meaning that the key shell has an empty value. Mapping values of implicit keys, if not on the same line, must always be indented more than the corresponding mapping key (spec):
The block node’s properties may span across several lines. In this case, they must be indented by at least one more space than the block collection, regardless of the indentation of the block collection entries.
OTOH, in the second example:
windows:
- shell:
panes:
- echo hello
panes: is on a deeper indentation level compared to shell:. This means that it is parsed as value of the key shell and thus starts a new, nested block mapping.
Finally, mind that since - is treated as part of the indentation, „indenting by two spaces“ could also mean this:
windows:
- shell:
panes:
- echo hello
Note how the - are not more indented than their mapping keys. This works because the spec says:
Since people perceive the “-” indicator as indentation, nested block sequences may be indented by one less space to compensate, except, of course, if nested inside another block sequence (block-out context vs. block-in context).
The trouble is that you cannot simply replace every two spaces with four spaces. That is because in this pair of lines:
- shell:
panes:
these two spaces in the second line:
panes:
^^
Are an abbrevation for the "- " in the line above. If the second line were not abbreviated, then the pair of lines would be:
- shell:
- panes:
So when doubling the indentation, the second of these line should only have its first pair of spaces doubled, not the second. That would yield the correct indentation for the pair:
- shell:
panes:
So, if you only expand the first pair of spaces in the "panes:" line, you get:
windows:
- shell:
panes:
- git status
Which correctly parses to the expected result.

YAML How many spaces per indent?

Is there any difference if i use one space, two or four spaces per indent level in YAML?
Are there any specific rules for space numbers per Structure type??
For example 4 spaces for nesting maps , 1 space per list item etc??
I am writing a yaml configuration file for elastic beanstalk .ebextensions and i am having really hard time constructing this correctly. Although i have valid yaml in YAML Validator elastic beanstalk seems to understand a different structure.
There is no requirement in YAML to indent any concrete number of spaces. There is also no requirement to be consistent. So for example, this is valid YAML:
a:
b:
- c
- d
- e
f:
"ghi"
Some rules might be of interest:
Flow content (i.e. everything that starts with { or [) can span multiple lines, but must be indented at least as many spaces as the surrounding current block level.
Block list items can (but don't need to) have the same indentation as the surrounding block level because - is considered part of the indentation:
a: # top-level key
- b # value of that key, which is a list
- c
c: # next top-level key
d # non-list value which must be more indented
The YAML spec for v 1.2 merely says that
In YAML block styles, structure is determined by indentation. In general, indentation is defined as a zero or more space characters at the start of a line.
To maintain portability, tab characters must not be used in indentation, since different systems treat tabs differently. Note that most modern editors may be configured so that pressing the tab key results in the insertion of an appropriate number of spaces.
The amount of indentation is a presentation detail and must not be used to convey content information.
So you can set the indent depth to your preference, as long as you use spaces and not tabs. Interestingly, IntelliJ uses 2 spaces by default.
INDENTATION
The suggested syntax for YAML files is to use 2 spaces for indentation, but YAML will follow whatever indentation system that the individual file uses. Indentation of two spaces works very well for SLS files given the fact that the data is uniform and not deeply nested.
NESTED DICTIONARIES
When dictionaries are nested within other data structures (particularly lists), the indentation logic sometimes changes. Examples of where this might happen include context and default options from the file.managed state:
/etc/http/conf/http.conf:
file:
- managed
- source: salt://apache/http.conf
- user: root
- group: root
- mode: 644
- template: jinja
- context:
custom_var: "override"
- defaults:
custom_var: "default value"
other_var: 123
Notice that while the indentation is two spaces per level, for the values under the context and defaults options there is a four-space indent. If only two spaces are used to indent, then those keys will be considered part of the same dictionary that contains the context key, and so the data will not be loaded correctly. If using a double indent is not desirable, then a deeply-nested dict can be declared with curly braces:
/etc/http/conf/http.conf:
file:
- managed
- source: salt://apache/http.conf
- user: root
- group: root
- mode: 644
- template: jinja
- context: {
custom_var: "override" }
- defaults: {
custom_var: "default value",
other_var: 123 }
you can read more from this link

How to remove '---' on top of a YAML file?

I am modifying a YAML file in Ruby. After I write back the modified YAML, I see a --- added on top of the file. How is this getting added and how do I get rid of it?
YAML spec says:
YAML uses three dashes (“---”) to separate directives from document content. This also serves to signal the start of a document if no directives are present.
Example:
# Ranking of 1998 home runs
---
- Mark McGwire
- Sammy Sosa
- Ken Griffey
# Team ranking
---
- Chicago Cubs
- St Louis Cardinals
So if you have multiple documents per YAML file, you have to separate them by three dashes. If you only have one document, you can remove/omit it (I never had a problem with YAML in ruby if three-dashes was missing). The reason why it's added when you yamlify your object is that, I guess, the dumper is written "by the spec" and doesn't care to implement such "shortcuts" (omit three-dashes when it's only one document).

Jekyll/Liquid - how to add large blocks of text to YAML front matter?

I'm trying to implement a service catalog in Jekyll, in which each of 20 or 30 pages will contain a 7x2 table. The left column will hold labels, e.g. Overview, Available To, etc, while the right column will hold between one line and several paragraphs of text. I was hoping to characterize the right column with Liquid variables, e.g. {overview}, {availableTo}
I've noticed that the YAML seems to be very picky about line breaks, and accordingly I've had to input these paragraphs and their markup on one line which can go on for several screen-widths. This is a problem because it's annoying, and also because I'd like these front-matters to be editable by technical but non-webdev users. Is there a way to have the front matter tolerate breaks?
Alternatively, is there a way that I could populate this table with the {content} section, without having to recode the table into it each time?
Yaml syntax for multi-line strings is this one:
body: |
This is a multi-line string.
"special" metacharacters may
appear here. The extent of this string is
indicated by indentation.
Notice that the first line must be an space followed by the | character and a new line. Then you must indent the text one level more than its parent.
Consequently, you can create one item this way:
item1:
overview: |
overview text
more overview text
available_to: 2012-01-01
foo: |
foo text
more foo text
It seems to me that you also want to arrange your items in order. You can employ a yaml list for that:
catalog:
- id: item 1
overview: |
overview text
more overview text
available_to: 2012-01-01
foo: |
foo text
more foo text
...
- id: item2
overview: <similar to above>

Indenting a YAML sequence inside a mapping

Should the following be valid?
parent:
- child
- child
So what we have is a sequence of values inside a mapping.
The specific question is about whether the indentation for the 2nd and 3rd lines is valid. The Ruby YAML.dump generated this code, but the Yaml parser here rejects it, because the child lines are not indented.
i.e. it wants something like:
parent:
- child
- child
Who is right?
Looking at the YAML spec, it's certainly not obvious, and the line
The “-”, “?” and “:” characters used to denote block collection entries are perceived by people to be part of the indentation
doesn't help much.
Yes, that is legal YAML. The relevant text from the spec is here:
Since people perceive the “-” indicator as indentation, nested block sequences may be indented by one less space to compensate, except, of course, if nested inside another block sequence (block-out context vs. block-in context).
and the subsequent example 8.22:
sequence: !!seq
- entry
- !!seq
- nested
mapping: !!map
foo: bar

Resources