块风格

2022.06.17

本文按照YAML官方文档1.2.2版本翻译总结而成

https://yaml.org/spec/1.2.2/#chapter-8-block-style-productions

YAML’s block styles employ indentation rather than indicators to denote structure. This results in a more human readable (though less compact) notation.

8.1. Block Scalar Styles

YAML provides two block scalar styles, literal and folded. Each provides a different trade-off between readability and expressive power.

8.1.1. Block Scalar Headers

Block scalars are controlled by a few indicators given in a header preceding the content itself. This header is followed by a non-content line break with an optional comment. This is the only case where a comment must not be followed by additional comment lines.

Note: See Production Parameters for the definition of the t variable.

Example 8.1 Block Scalar Header

- | # Empty header↓ literal - >1 # Indentation indicator↓ ·folded - |+ # Chomping indicator↓ keep - >1- # Both indicators↓ ·strip[ "literal\n", " folded\n", "keep\n\n", " strip" ]
  

Legend:

8.1.1.1. Block Indentation Indicator

Every block scalar has a content indentation level. The content of the block scalar excludes a number of leading spaces on each line up to the content indentation level.

If a block scalar has an indentation indicator, then the content indentation level of the block scalar is equal to the indentation level of the block scalar plus the integer value of the indentation indicator character.

If no indentation indicator is given, then the content indentation level is equal to the number of leading spaces on the first non-empty line of the contents. If there is no non-empty line then the content indentation level is equal to the number of spaces on the longest line.

It is an error if any non-empty line does not begin with a number of spaces greater than or equal to the content indentation level.

It is an error for any of the leading empty lines to contain more spaces than the first non-empty line.

A YAML processor should only emit an explicit indentation indicator for cases where detection will fail.

Example 8.2 Block Indentation Indicator

- |° ·detected - >° · ·· ··# detected - |1 ··explicit - >° ·→ ·detected[ "detected\n", "\n\n# detected\n", " explicit\n", "\t\ndetected\n" ]
  

Legend:

Example 8.3 Invalid Block Scalar Indentation Indicators

- | ·· ·text - > ··text ·text - |2 ·textERROR: - A leading all-space line must not have too many spaces. - A following text line must not be less indented. - The text is less indented than the indicated level.
  

8.1.1.2. Block Chomping Indicator

Chomping controls how final line breaks and trailing empty lines are interpreted. YAML provides three chomping methods:

The chomping method used is a presentation detail and must not be used to convey content information.

The interpretation of the final line break of a block scalar is controlled by the chomping indicator specified in the block scalar header.

Example 8.4 Chomping Final Line Break

strip: |- text↓ clip: | text↓ keep: |+ text↓{ "strip": "text", "clip": "text\n", "keep": "text\n" }
  

Legend:

The interpretation of the trailing empty lines following a block scalar is also controlled by the chomping indicator specified in the block scalar header.

Explicit comment lines may follow the trailing empty lines. To prevent ambiguity, the first such comment line must be less indented than the block scalar content. Additional comment lines, if any, are not so restricted. This is the only case where the indentation of comment lines is constrained.

Example 8.5 Chomping Trailing Lines

# Strip # Comments: strip: |- # text↓ ··⇓ ·# Clip ··# comments: ↓ clip: | # text↓ ·↓ ·# Keep ··# comments: ↓ keep: |+ # text↓ ↓ ·# Trail ··# comments.{ "strip": "# text", "clip": "# text\n", "keep": "# text\n\n" }
  

Legend:

If a block scalar consists only of empty lines, then these lines are considered as trailing lines and hence are affected by chomping.

Example 8.6 Empty Scalar Chomping

strip: >- ↓ clip: > ↓ keep: |+ ↓{ "strip": "", "clip": "", "keep": "\n" }
  

Legend:

8.1.2. Literal Style

The literal style is denoted by the “|” indicator. It is the simplest, most restricted and most readable scalar style.

Example 8.7 Literal Scalar

|↓ ·literal↓ ·→text↓ ↓"literal\n\ttext\n"
  

Legend:

Inside literal scalars, all (indented) characters are considered to be content, including white space characters. Note that all line break characters are normalized. In addition, empty lines are not folded, though final line breaks and trailing empty lines are chomped.

There is no way to escape characters inside literal scalars. This restricts them to printable characters. In addition, there is no way to break a long literal line.

Example 8.8 Literal Content

| · ·· ··literal↓ ···↓ ·· ··text↓ ↓ ·# Comment"\n\nliteral\n·\n\ntext\n"
  

Legend:

8.1.3. Folded Style

The folded style is denoted by the “>” indicator. It is similar to the literal style; however, folded scalars are subject to line folding.

Example 8.9 Folded Scalar

>↓ ·folded↓ ·text↓ ↓"folded text\n"
  

Legend:

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

Example 8.10 Folded Lines

> ·folded↓ ·line↓ ↓ ·next ·line↓ * bullet * list * lines ·last↓ ·line↓ # Comment"\nfolded line\nnext line\n \ * bullet\n \n * list\n \ * lines\n\nlast line\n"
  

Legend:

(The following three examples duplicate this example, each highlighting different productions.)

Lines starting with white space characters (more-indented lines) are not folded.

Example 8.11 More Indented Lines

> folded line next line ···* bullet↓ ↓ ···* list↓ ···* lines↓ last line # Comment"\nfolded line\nnext line\n \ * bullet\n \n * list\n \ * lines\n\nlast line\n"
  

Legend:

Line breaks and empty lines separating folded and more-indented lines are also not folded.

Example 8.12 Empty Separation Lines

> ↓ folded line↓ ↓ next line↓ * bullet * list * lines↓ ↓ last line # Comment"\nfolded line\nnext line\n \ * bullet\n \n * list\n \ * lines\n\nlast line\n"
  

Legend:

The final line break and trailing empty lines if any, are subject to chomping and are never folded.

Example 8.13 Final Empty Lines

> folded line next line * bullet * list * lines last line↓ ↓ # Comment"\nfolded line\nnext line\n \ * bullet\n \n * list\n \ * lines\n\nlast line\n"
  

Legend:

8.2. Block Collection Styles

For readability, block collections styles are not denoted by any indicator. Instead, YAML uses a lookahead method, where a block collection is distinguished from a plain scalar only when a key/value pair or a sequence entry is seen.

8.2.1. Block Sequences

A block sequence is simply a series of nodes, each denoted by a leading “-” indicator. The “-” indicator must be separated from the node by white space. This allows “-” to be used as the first character in a plain scalar if followed by a non-space character (e.g. “-42”).

Example 8.14 Block Sequence

block sequence: ··- one↓ - two : three↓{ "block sequence": [ "one", { "two": "three" } ] }
  

Legend:

The entry node may be either completely empty, be a nested block node or use a compact in-line notation. The compact notation may be used when the entry is itself a nested block collection. In this case, both the “-” indicator and the following spaces are considered to be part of the indentation of the nested collection. Note that it is not possible to specify node properties for such a collection.

Example 8.15 Block Sequence Entry Types

-° # Empty - | block node -·- one # Compact ··- two # sequence - one: two # Compact mapping[ null, "block node\n", [ "one", "two" ], { "one": "two" } ]
  

Legend:

8.2.2. Block Mappings

A Block mapping is a series of entries, each presenting a key/value pair.

Example 8.16 Block Mappings

block mapping: ·key: value↓{ "block mapping": { "key": "value" } }
  

Legend:

If the “?” indicator is specified, the optional value node must be specified on a separate line, denoted by the “:” indicator. Note that YAML allows here the same compact in-line notation described above for block sequence entries.

Example 8.17 Explicit Block Mapping Entries

? explicit key # Empty value↓° ? | block key↓ :·- one # Explicit compact ··- two # block value↓{ "explicit key": null, "block key\n": [ "one", "two" ] }
  

Legend:

If the “?” indicator is omitted, parsing needs to see past the implicit key, in the same way as in the single key/value pair flow mapping. Hence, such keys are subject to the same restrictions; they are limited to a single line and must not span more than 1024 Unicode characters.

In this case, the value may be specified on the same line as the implicit key. Note however that in block mappings the value must never be adjacent to the “:”, as this greatly reduces readability and is not required for JSON compatibility (unlike the case in flow mappings).

There is no compact notation for in-line values. Also, while both the implicit key and the value following it may be empty, the “:” indicator is mandatory. This prevents a potential ambiguity with multi-line plain scalars.

Example 8.18 Implicit Block Mapping Entries

plain key: in-line value °:° # Both empty "quoted key": - entry{ "plain key": "in-line value", null: null, "quoted key": [ "entry" ] }
  

Legend:

A compact in-line notation is also available. This compact notation may be nested inside block sequences and explicit block mapping entries. Note that it is not possible to specify node properties for such a nested mapping.

Example 8.19 Compact Block Mappings

- sun: yellow↓ - ? earth: blue↓ : moon: white↓[ { "sun": "yellow" }, { { "earth": "blue" }: { "moon": "white" } } ]
  

Legend:

8.2.3. Block Nodes

YAML allows flow nodes to be embedded inside block collections (but not vice-versa). Flow nodes must be indented by at least one more space than the parent block collection. Note that flow nodes may begin on a following line.

It is at this point that parsing needs to distinguish between a plain scalar and an implicit key starting a nested block mapping.

Example 8.20 Block Node Types

-↓ ··"flow in block"↓ -·> Block scalar↓ -·!!map # Block collection foo : bar↓[ "flow in block", "Block scalar\n", { "foo": "bar" } ]
  

Legend:

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.

Example 8.21 Block Scalar Nodes

literal: |2 ··value folded:↓ ···!foo ··>1 ·value{ "literal": "value", "folded": !<!foo> "value" }
  

Legend:

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] versus [BLOCK-IN context]).

Example 8.22 Block Collection Nodes

sequence: !!seq - entry - !!seq - nested mapping: !!map foo: bar{ "sequence": [ "entry", [ "nested" ] ], "mapping": { "foo": "bar" } }
  

Legend: