Copyright © 2001-2004 Oren Ben-Kiki, Clark Evans, Brian Ingerson
Status of this Document
This specification is a draft reflecting consensus reached by members of the yaml-core mailing list. Any questions regarding this draft should be raised on this list. We expect all further changes will be strictly limited to wording corrections and fixing production bugs.
We wish to thank implementers who have tirelessly tracked earlier versions of this specification, and our fabulous user community whose feedback has both validated and clarified our direction.
Abstract
YAML™ (rhymes with “camel”) is a human-friendly, cross language, Unicode based data serialization language designed around the common native data structures of agile programming languages. It is broadly useful for programming needs ranging from configuration files to Internet messaging to object persistence to data auditing. Together with the Unicode standard for characters, this specification provides all the information necessary to understand YAML Version 1.1 and to creating programs that process YAML information.
Table of Contents
“YAML Ain't Markup Language” (abbreviated YAML) is a data serialization language designed to be human-friendly and work well with modern programming languages for common everyday tasks. This specification is both an introduction to the YAML language and the concepts supporting it and also a complete reference of the information needed to develop applications for processing YAML.
Open, interoperable and readily understandable tools have advanced computing immensely. YAML was designed from the start to be useful and friendly to people working with data. It uses Unicode printable characters, some of which provide structural information and the rest containing the data itself. YAML achieves a unique cleanness by minimizing the amount of structural characters, and allowing the data to show itself in a natural and meaningful way. For example, indentation may be used for structure, colons separate mapping key: value pairs, and dashes are used to “bullet” lists.
There are myriad flavors of data structures, but they can all be adequately represented with three basic primitives: mappings (hashes/dictionaries), sequences (arrays/lists) and scalars (strings/numbers). YAML leverages these primitives and adds a simple typing system and aliasing mechanism to form a complete language for serializing any data structure. While most programming languages can use YAML for data serialization, YAML excels in those languages that are fundamentally built around the three basic primitives. These include the new wave of agile languages such as Perl, Python, PHP, Ruby and Javascript.
There are hundreds of different languages for programming, but only a handful of languages for storing and transferring data. Even though its potential is virtually boundless, YAML was specifically created to work well for common use cases such as: configuration files, log files, interprocess messaging, cross-language data sharing, object persistence and debugging of complex data structures. When data is easy to view and understand, programming becomes a simpler task.
The design goals for YAML are:
YAML is easily readable by humans.
YAML matches the native data structures of agile languages.
YAML data is portable between programming languages.
YAML has a consistent model to support generic tools.
YAML supports one-pass processing.
YAML is expressive and extensible.
YAML is easy to implement and use.
YAML's initial direction was set by the data serialization and markup language discussions among SML-DEV members. Later on it directly incorporated experience from Brian Ingerson's Perl module Data::Denter. Since then YAML has matured through ideas and support from its user community.
YAML integrates and builds upon concepts described by C, Java, Perl, Python, Ruby, RFC0822 (MAIL), RFC1866 (HTML), RFC2045 (MIME), RFC2396 (URI), XML, SAX and SOAP.
The syntax of YAML was motivated by Internet Mail (RFC0822) and remains partially compatible with that standard. Further, borrowing from MIME (RFC2045), YAML's top-level production is a stream of independent documents; ideal for message-based distributed processing systems.
YAML's indentation based scoping is similar to Python's (without the ambiguities caused by tabs). Indented blocks facilitate easy inspection of the data's structure. YAML's literal style leverages this by enabling formatted text to be cleanly mixed within an indented structure without troublesome escaping. YAML also allows the use of traditional indicator-based scoping similar to Perl's. Such flow content can be freely nested inside indented blocks.
YAML's double quoted style uses familiar C-style escape sequences. This enables ASCII encoding of non-printable or 8-bit (ISO 8859-1) characters such as “\x3B”. Non-printable 16-bit Unicode and 32-bit (ISO/IEC 10646) characters are supported with escape sequences such as “\u003B” and “\U0000003B”.
Motivated by HTML's end-of-line normalization, YAML's line folding employs an intuitive method of handling line breaks. A single line break is folded into a single space, while empty lines are interpreted as line break characters. This technique allows for paragraphs to be word-wrapped without affecting the canonical form of the content.
YAML's core type system is based on the requirements of agile languages such as Perl, Python, and Ruby. YAML directly supports both collection (mapping, sequence) and scalar content. Support for common types enables programmers to use their language's native data structures for YAML manipulation, instead of requiring a special document object model (DOM).
Like XML's SOAP, YAML supports serializing native graph data structures through an aliasing mechanism. Also like SOAP, YAML provides for application-defined types. This allows YAML to represent rich data structures required for modern distributed computing. YAML provides globally unique type names using a namespace mechanism inspired by Java's DNS based package naming convention and XML's URI based namespaces.
YAML was designed to support incremental interfaces that includes both input pull-style and output push-style one-pass (SAX-like) interfaces. Together these enable YAML to support the processing of large documents, such as a transaction log, or continuous streams, such as a feed from a production machine.
Newcomers to YAML often search for its correlation to the eXtensible Markup Language (XML). While the two languages may actually compete in several application domains, there is no direct correlation between them.
YAML is primarily a data serialization language. XML was designed to be backwards compatible with the Standard Generalized Markup Language (SGML) and thus had many design constraints placed on it that YAML does not share. Inheriting SGML's legacy, XML is designed to support structured documentation, where YAML is more closely targeted at data structures and messaging. Where XML is a pioneer in many domains, YAML is the result of lessons learned from XML and other technologies.
It should be mentioned that there are ongoing efforts to define standard XML/YAML mappings. This generally requires that a subset of each language be used. For more information on using both XML and YAML, please visit http://yaml.org/xml/index.html.
This specification uses key words based on RFC2119 to indicate requirement level. In particular, the following words are used to describe the actions of a YAML processor:
The word may, or the adjective optional, mean that conforming YAML processors are permitted, but need not behave as described.
The word should, or the adjective recommended, mean that there could be reasons for a YAML processor to deviate from the behavior described, but that such deviation could hurt interoperability and should therefore be advertised with appropriate notice.
The word must, or the term required or shall, mean that the behavior described is an absolute requirement of the specification.
This section provides a quick glimpse into the expressive power of YAML. It is not expected that the first-time reader grok all of the examples. Rather, these selections are used as motivation for the remainder of the specification.
YAML's block collections use indentation for scope and begin each entry on its own line. Block sequences indicate each entry with a dash and space ( “-”). Mappings use a colon and space (“: ”) to mark each mapping key: value pair.
YAML also has flow styles, using explicit indicators rather than indentation to denote scope. The flow sequence is written as a comma separated list within square brackets. In a similar manner, the flow mapping uses curly braces.
YAML uses three dashes (“---”) to separate documents within a stream. Three dots ( “...”) indicate the end of a document without starting a new one, for use in communication channels. Comment lines begin with the Octothorpe (usually called the “hash” or “pound” sign - “#”).
Repeated nodes are first identified by an anchor (marked with the ampersand - “&”), and are then aliased (referenced with an asterisk - “*”) thereafter.
A question mark and space (“? ”) indicate a complex mapping key. Within a block collection, key: value pairs can start immediately following the dash, colon or question mark.
Scalar content can be written in block form using a literal style (“|”) where all line breaks count. Or they can be written with the folded style (“>”) where each line break is folded to a space unless it ends an empty or a “more indented” line.
YAML's flow scalars include the plain style (most examples thus far) and quoted styles. The double quoted style provides escape sequences. The single quoted style is useful when escaping is not needed. All flow scalars can span multiple lines; line breaks are always folded.
In YAML, untagged nodes are given an type depending on the application. The examples in this specification generally use the “seq”, “map” and “str” types from the YAML tag repository. A few examples also use the “int” and “float” types. The repository includes additional types such as “null”, “bool”, “set” and others.
Explicit typing is denoted with a tag using the exclamantion point (“!”) symbol. Global tags are URIs and may be specified in a shorthand form using a handle. Application-specific local tags may also be used.
Below are two full-length examples of YAML. On the left is a sample invoice; on the right is a sample log file.
YAML is both a text format and a method for presenting any data structure in this format. Therefore, this specification defines two concepts: a class of data objects called YAML representations, and a syntax for presenting YAML representations as a series of characters, called a YAML stream. A YAML processor is a tool for converting information between these complementary views. It is assumed that a YAML processor does its work on behalf of another module, called an application. This chapter describes the information structures a YAML processor must provide to or obtain from the application.
YAML information is used in two ways: for machine processing, and for human consumption. The challenge of reconciling these two perspectives is best done in three distinct translation stages: representation, serialization, and presentation. Representation addresses how YAML views native data structures to achieve portability between programming environments. Serialization concerns itself with turning a YAML representation into a serial form, that is, a form with sequential access constraints. Presentation deals with the formatting of a YAML serialization as a series of characters in a human-friendly manner.
A YAML processor need not expose the serialization or representation stages. It may translate directly between native data structures and a character stream (dump and load in the diagram above). However, such a direct translation should take place so that the native data structures are constructed only from information available in the representation.
This section details the processes shown in the diagram above. Note a YAML processor need not provide all these processes. For example, a YAML library may provide only YAML input ability, for loading configuration files, or only output ability, for sending data to other applications.
YAML represents any native data structure using three node kinds: the sequence, the mapping and the scalar. By sequence we mean an ordered series of entries, by mapping we mean an unordered association of unique keys to values, and by scalar we mean any datum with opaque structure presentable as a series of Unicode characters. Combined, these primitives generate directed graph structures. These primitives were chosen because they are both powerful and familiar: the sequence corresponds to a Perl array and a Python list, the mapping corresponds to a Perl hash table and a Python dictionary. The scalar represents strings, integers, dates and other atomic data types.
Each YAML node requires, in addition to its kind and content, a tag specifying its data type. Type specifiers are either global URIs, or are local in scope to a single application. For example, an integer is represented in YAML with a scalar plus the global tag “tag:yaml.org,2002:int”. Similarly, an invoice object, particular to a given organization, could be represented as a mapping together with the local tag “!invoice”. This simple model can represent any data structure independent of programming language.
For sequential access mediums, such as an event callback API, a YAML representation must be serialized to an ordered tree. Since in a YAML representation, mapping keys are unordered and nodes may be referenced more than once (have more than one incoming “arrow”), the serialization process is required to impose an ordering on the mapping keys and to replace the second and subsequent references to a given node with place holders called aliases. YAML does not specify how these serialization details are chosen. It is up to the YAML processor to come up with human-friendly key order and anchor names, possibly with the help of the application. The result of this process, a YAML serialization tree, can then be traversed to produce a series of event calls for one-pass processing of YAML data.
The final output process is presenting the YAML serializations as a character stream in a human-friendly manner. To maximize human readability, YAML offsers a rich set of stylistic options which go far beyond the minimal functional needs of simple data storage. Therefore the YAML processor is required to introduce various presentation details when creating the stream, such as the choice of node styles, how to format content, the amount of indentation, which tag handles to use, the node tags to leave unspecified, the set of directives to provide and possibly even what comments to add. While some of this can be done with the help of of the application, in general this process should guided by the preferences of the user.
Parsing is the inverse process of presentation, it takes a stream of characters and produces a series of events. Parsing discards all the details introduced in the presentation process, reporting only the serialization events. Parsing can fail fue to ill-formed input.
Composing takes a series of serialization events and produces a representation graph. Composing discards all the serialization details introduced in the serialization process, producing only the representation graph. Composing can fail due to any of several reasons, detailed below.
The final input process is constructing native data structures from the YAML representation. Construction must be based only on the information available in the representation, and not on additional serialization or presentation details such as comments, directives, mapping key order, node styles, content format, indentation levels etc. Construction can fail due to the unavailability of the required native data types.
This section specifies the formal details of the results of the above processes. To maximize data portability between programming languages and implementations, users of YAML should be mindful of the distinction between serialization or presentation properties and those which are part of the YAML representation. Thus, while imposing a order on mapping keys is necessary for flattening YAML representations to a sequential access medium, this serialization detail must not be used to convey application level information. In a similar manner, while indentation technique and a choice of a node style are needed for the human readability, these presentation details are neither part of the YAML serialization nor the YAML representation. By carefully separating properties needed for serialization and presentation, YAML representations of application information will be consistent and portable between various programming environments.
YAML's representation of native data is a rooted, connected, directed graph of tagged nodes. By “directed graph” we mean a set of nodes and directed edges (“arrows”), where each edge connects one node to another (see a formal definition). All the nodes must be reachable from the root node via such edges. Note that the YAML graph may include cycles, and a node may have more than one incoming edge.
Nodes that are defined in terms of other nodes are collections and nodes that are independent of any other nodes are scalars. YAML supports two kinds of collection nodes, sequences and mappings. Mapping nodes are somewhat tricky because their keys are unordered and must be unique.
YAML nodes have content of one of three kinds: scalar, sequence, or mapping. In addition, each node has a tag which serves to restrict the set of possible values which the node's content can have.
The content of a scalar node is an opaque datum that can be presented as a series of zero or more Unicode characters.
The content of a sequence node is an ordered series of zero or more nodes. In particular, a sequence may contain the same node more than once or it could even contain itself (directly or indirectly).
The content of a mapping node is an unordered set of key: value node pairs, with the restriction that each of the keys is unique. YAML places no further restrictions on the nodes. In particular, keys may be arbitrary nodes, the same node may be used as the value of several key: value pairs, and a mapping could even contain itself as a key or a value (directly or indirectly).
When appropriate, it is convenient to consider sequences and mappings together, as collections. In this view, sequences are treated as mappings with integer keys starting at zero. Having a unified collections view for sequences and mappings is helpful both for creating practical YAML tools and APIs and for theoretical analysis.
YAML represents type information of native data structures with a simple identifier, called a tag. Global tags are are URIs and hence globally unique across all applications. The “tag”: URI scheme (mirror) is recommended for all global YAML tags. In contrast, local tags are specific to a single application. Local tags start with “!”, are not URIs and are not expected to be globally unique. YAML provides a “TAG” directive to make tag notation less verbose; it also offers easy migration from local to global tags. To ensure this, local tags are restricted to the URI character set and use URI character escaping.
YAML does not mandate any special relationship between different tags that begin with the same substring. Tags ending with URI fragments (containing “#”) are no exception; tags that share the same base URI but differ in their fragment part are considered to be different, independent tags. By convention, fragments are used to identify different “variants” of a tag, while “/” is used to define nested tag “namespace” hierarchies. However, this is merely a convention, and each tag may employ its own rules. For example, Perl tags may use “::” to express namespace hierarchies, Java tags may use “.”, etc.
YAML tags are used to associate meta information with each node. In particular, each tag must specify the expected node kind (scalar, sequence, or mapping). Scalar tags must also provide mechanism for converting formatted content to a canonical form for supporting equality testing. Furthermore, a tag may provide additional information such as the set of allowed content values for validation, a mechanism for tag resolution, or any other data that is applicable to all of the tag's nodes.
Since YAML mappings require key uniqueness, representations must include a mechanism for testing the equality of nodes. This is non-trivial since YAML allows various ways to format a given scalar content. For example, the integer eleven can be written as “013” (octal) or “0xB” (hexadecimal). If both forms are used as keys in the same mapping, only a YAML processor which recognizes integer formats would correctly flag the duplicate key as an error.
YAML supports the need for scalar equality by requiring that every scalar tag must specify a mechanism to producing the canonical form of any formatted content. This form is a Unicode character string which presents the content and can be used for equality testing. While this requirement is stronger than a well defined equality operator, it has other uses, such as the production of digital signatures.
Two nodes must have the same tag and content to be equal. Since each tag applies to exactly one kind, this implies that the two nodes must have the same kind to be equal. Two scalars are equal only when their tags and canonical forms are equal character-by-character. Equality of collections is defined recursively. Two sequences are equal only when they have the same tag and length, and each node in one sequence is equal to the corresponding node in the other sequence. Two mappings are equal only when they have the same tag and an equal set of keys, and each key in this set is associated with equal values in both mappings.
Two nodes are identical only when they represent the same native data structure. Typically, this corresponds to a single memory address. Identity should not be confused with equality; two equal nodes need not have the same identity. A YAML processor may treat equal scalars as if they were identical. In contrast, the separate identity of two distinct but equal collections must be preserved.
To express a YAML representation using a serial API, it necessary to impose an order on mapping keys and employ alias nodes to indicate a subsequent occurrence of a previously encountered node. The result of this process is a serialization tree, where each node has an ordered set of children. This tree can be traversed for a serial event based API. Construction of native structures from the serial interface should not use key order or anchors for the preservation of important data.
In the representation model, mapping keys do not have an order. To serialize a mapping, it is necessary to impose an ordering on its keys. This order is a serialization detail and should not be used when composing the representation graph (and hence for the preservation of important data). In every case where node order is significant, a sequence must be used. For example, an ordered mapping can be represented as a sequence of mappings, where each mapping is a single key: value pair. YAML provides convenient compact notation for this case.
In the representation graph, a node may appear in more than one collection. When serializing such data, the first occurrence of the node is identified by an anchor and each subsequent occurrence is serialized as an alias node which refers back to this anchor. Otherwise, anchor names are a serialization detail and are discarded once composing is completed. When composing a representation graph from serialized events, an alias node refers to the most recent node in the serialization having the specified anchor. Therefore, anchors need not be unique within a serialization. In addition, an anchor need not have an alias node referring to it. It is therefore possible to provide an anchor for all nodes in serialization.
A YAML presentation is a stream of Unicode characters making use of of styles, formats, comments, directives and other presentation details to present a YAML serialization in a human readable way. Although a YAML processor may provide these details when parsing, they should not be reflected in the resulting serialization. YAML allows several serializations to be contained in the same YAML character stream as a series of documents separated by document boundary markers. Documents appearing in the same stream are independent; that is, a node must not appear in more than one serialization tree or representation graph.
Each node is presented in some style, depending on its kind. The node style is a presentation detail and is not reflected in the serialization tree or representation graph. There are two groups of styles, block and flow. Block styles use indentation to denote nesting and scope within the document. In contrast, flow styles rely on explicit indicators to denote nesting and scope.
YAML provides a rich set of scalar styles. Block scalar styles include the literal style and the folded style; flow scalar styles include the plain style and two quoted styles, the single quoted style and the double quoted style. These styles offer a range of trade-offs between expressive power and readability.
Normally, the content of block collections begins on the next line. In most cases, YAML also allows block collections to start in-line for more compact notation when nesting block sequences and block mappings inside each other. When nesting flow collections, a flow mapping with a single key: value pair may be specified directly inside a flow sequence, allowing for a compact “ordered mapping” notation.
YAML allows scalar content to be presented in several formats. For example, the boolean “true” might also be written as “yes”. Tags must specify a mechanism for converting any formatted scalar content to a canonical form for use in equality testing. Like node style, the format is a presentation detail and is not reflected in the serialization tree and representation graph.
Comments are a presentation detail and must not have any effect on the serialization tree or representation graph. In particular, comments are not associated with a particular node. The usual purpose of a comment is to communicate between the human maintainers of a file. A typical example is comments in a configuration file. Comments may not appear inside scalars, but may be interleaved with such scalars inside collections.
Each document may be associated with a set of directives. A directive has a name and an optional sequence of parameters. Directives are instructions to the YAML processor, and like all other presentation details are not reflected in the YAML serialization tree or representation graph. This version of YAML defines a two directives, “YAML” and “TAG”. All other directives are reserved for future versions of YAML.
The process of loading native data structures from a YAML stream has several potential failure points. The character stream may be ill-formed, aliases may be unidentified, unspecified tags may be unresolvable, tags may be unrecognized, the content may be invalid, and a native type may be unavailable. Each of these failures results with an incomplete loading.
A partial representation need not resolve the tag of each node, and the canonical form of scalar content need not be available. This weaker representation is useful for cases of incomplete knowledge of the types used in the document. In contrast, a complete representation specifies the tag of each node, and provides the canonical form of scalar content, allowing for equality testing. A complete representation is required in order to construct native data structures.
A well-formed character stream must match the productions specified in the next chapter. Successful loading also requires that each alias shall refer to a previous node identified by the anchor. A YAML processor should reject ill-formed streams and unidentified aliases. A YAML processor may recover from syntax errors, possibly by ignoring certain parts of the input, but it must provide a mechanism for reporting such errors.
It is not required that all the tags of the complete representation be explicitly specified in the character stream. During parsing, nodes that omit the tag are given a non-specific tag: “?” for plain scalars and “!” for all other nodes. These non-specific tags must be resolved to a specific tag (either a local tag or a global tag) for a complete representation to be composed.
Resolving the tag of a node must only depend on the following three parameters: the non-specific tag of the node, the path leading from the root node to the node, and the content (and hence the kind) of the node. In particular, resolution must not consider presentation details such as comments, indentation and node style. Also, resolution must not consider the content of any other node, except for the content of the key nodes directly along the path leading from the root node to the resolved node. In particular, resolution must not consider the content of a sibling node in a collection or the content of the value node associated with a resolved key node.
Tag resolution is specific to the application, hence a YAML processor should provide a mechanism allowing the application to specify the tag resolution rules. It is recommended that nodes having the “!” non-specific tag should be resolved as “tag:yaml.org,2002:seq”, “tag:yaml.org,2002:map” or “tag:yaml.org,2002:str” depending on the node's kind. This convention allows the author of a YAML character stream to exert some measure of control over the tag resolution process. By explicitly specifying a plain scalar has the “!” non-specific tag, the node is resolved as a string, as if it was quoted or written in a block style. Note, however, that each application may override this behavior. For example, an application may automatically detect the type of programming language used in source code presented as a non-plain scalar and resolve it accordingly.
When a node has more than one occurence (using an anchor and alias nodes), tag resolution must depend only on the path to the first occurence of the node. Typically, the path leading to a node is sufficient to determine its specific tag. In cases where the path does not imply a single specific tag, the resolution also needs to consider the node content to select amongst the set of possible tags. Thus, plain scalars may be matched against a set of regular expressions to provide automatic resolution of integers, floats, timestamps and similar types. Similarly, the content of mapping nodes may be matched against sets of expected keys to automatically resolve points, complex numbers and similar types.
The combined effect of these rules is to ensure that tag resolution can be performed as soon as a node is first encountered in the stream, typically before its content is parsed. Also, tag resolution only requires refering to a relatively small number of previously parsed nodes. Thus, tag resolution in one-pass processors is both possible and practical.
If a document contains unresolved tags, the YAML processor is unable to compose a complete representation graph. In such a case, the YAML processor may compose an partial representation, based on each node's kind and allowing for non-specific tags.
To be valid, a node must have a tag which is recognized by the YAML processor and its content must satisfy the constraints imposed by this tag. If a document contains a scalar node with an unrecognized tag or invalid content, only a partial representation may be composed. In contrast, a YAML processor can always compose a complete representation for an unrecognized or an invalid collection, since collection equality does not depend upon knowledge of the collection's data type. However, such a complete representation can not be used to construct a native data structure.
In a given processing environment, there need not be an available native type corresponding to a given tag. If a node's tag is unavailable, a YAML processor will not be able to construct a native data structure for it. In this case, a complete representation may still be composed, and an application may wish to use this representation directly.
Following are the BNF productions defining the syntax of YAML character streams. To make this chapter easier to follow, production names use Hungarian-style notation:
A production matching no characters.
A production matching one or more characters starting and ending with a special (non-space) character.
A production matching a single line break.
A production matching one or more characters starting and ending with a non-break character.
A production matching one or more characters starting and ending with a space character.
A production matching one or more characters starting and ending with a non-space character.
A production matching a sequence of one or more characters, starting with an X- character and ending with a Y- character.
A production matching one or more lines (shorthand for s-b-).
A production as above, with the additional property that the indentation level used is greater than the specified n parameter.
Productions are generally introduced in a “bottom-up” order; basic productions are specified before the more complex productions using them. Examples accompanying the productions list display sample YAML text side-by-side with equivalent YAML text using only flow collections and double quoted scalars. For improved readability, the equivalent YAML text uses the “!!seq”, “!!map” and “!!str” shorthands instead of the verbatim “!<tag:yaml.org,2002:seq>”, “!<tag:yaml.org,2002:map>” and “!<tag:yaml.org,2002:str>” forms. These types are used to resolve all untagged nodes, except for a few examples that use the “!!int” and “!!float” types.
YAML streams use the printable subset of the Unicode character set. On input, a YAML processor must accept all printable ASCII characters, the space, tab, line break, and all Unicode characters beyond #x9F. On output, a YAML processor must only produce these acceptable characters, and should also escape all non-printable Unicode characters. The allowed character range explicitly excludes the surrogate block #xD800-#xDFFF, DEL #x7F, the C0 control block #x0-#x1F, the C1 control block #x80-#x9F, #xFFFE and #xFFFF. Any such characters must be presented using escape sequences.
|
All characters mentioned in this specification are Unicode code points. Each such code point is written as one or more octets depending on the character encoding used. Note that in UTF-16, characters above #xFFFF are written as four octets, using a surrogate pair. A YAML processor must support the UTF-16 and UTF-8 character encodings. If a character stream does not begin with a byte order mark (#FEFF), the character encoding shall be UTF-8. Otherwise it shall be either UTF-8, UTF-16 LE or UTF-16 BE as indicated by the byte order mark. On output, it is recommended that a byte order mark should only be emitted for UTF-16 character encodings. Note that the UTF-32 encoding is explicitly not supported. For more information about the byte order mark and the Unicode character encoding schemes see the Unicode FAQ.
|
In the examples, byte order mark characters are displayed as “⇔”.
Example 4.1. Byte Order Mark
⇔# Comment only.
Legend: c-byte-order-mark |
# This stream contains no
|
Indicators are characters that have special semantics used to describe the structure and content of a YAML document.
A “-” denotes a blocks equence entry.
|
A “?” denotes a mapping key.
|
A “:” denotes a mapping value.
|
Example 4.3. Block Structure Indicators
sequence:
Legend: c-sequence-entry c-mapping-key c-mapping-value |
%YAML 1.1
|
A “,” ends a flow collection entry.
|
A “[” starts a flow sequence.
|
A “]” ends a flow sequence.
|
A “{” starts a flow mapping.
|
A “}” ends a flow mapping.
|
Example 4.4. Flow Collection Indicators
sequence: [ one, two, ]
Legend: c-sequence-start c-sequence-end c-mapping-start c-mapping-end c-collect-entry |
%YAML 1.1
|
|
Example 4.5. Comment Indicator
# Comment only.
Legend: c-comment |
# This stream contains no
|
A “&” denotes a node's anchor property.
|
A “*” denotes an alias node.
|
A “!” denotes a node's tag.
|
Example 4.6. Node Property Indicators
anchored: !local &anchor value
Legend: c-anchor c-alias c-tag |
%YAML 1.1
|
A “|” denotes a literal block scalar.
|
A “>” denotes a folded block scalar.
|
Example 4.7. Block Scalar Indicators
literal: |
Legend: c-literal c-folded |
%YAML 1.1
|
A “'” surrounds a single quoted flow scalar.
|
A “"” surrounds a double quoted flow scalar.
|
Example 4.8. Quoted Scalar Indicators
single: 'text'
Legend: c-single-quote c-double-quote |
%YAML 1.1
|
|
|
Example 4.10. Invalid use of Reserved Indicators
commercial-at: @text
|
ERROR:
|
Any indicator character:
|
The Unicode standard defines the following line break characters:
|
A YAML processor must accept all the possible Unicode line break characters.
|
Line breaks can be grouped into two categories. Specific line breaks have well-defined semantics for breaking text into lines and paragraphs, and must be preserved by the YAML processor inside scalar content.
|
Generic line breaks do not carry a meaning beyond “ending a line”. Unlike specific line breaks, there are several widely used forms for generic line breaks.
|
Generic line breaks inside scalar content must be normalized by the YAML processor. Each such line break must be parsed into a single line feed character. The original line break form is a presentation detail and must not be used to convey content information.
|
Normalization does not apply to ignored (escaped or chomped) generic line breaks.
|
Outside scalar content, YAML allows any line break to be used to terminate lines.
|
On output, a YAML processor is free to present line breaks using whatever convention is most appropriate, though specific line breaks must be preserved in scalar content. These rules are compatible with Unicode's newline guidelines.
In the examples, line break characters are displayed as follows: “↓” or no glyph for a generic line break, “⇓” for a line separator and “¶” for a paragraph separator.
Example 4.11. Line Break Characters
|
Legend: b-generic b-line-separator b-paragraph-separator |
%YAML 1.1
|
The YAML syntax productions make use of the following character range definitions:
A non-break character:
|
An ignored space character outside scalar content. Such spaces are used for indentation and separation between tokens. To maintain portability, tab characters must not be used in these cases, 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.
|
Example 4.12. Invalid Use of Tabs
# Tabs do's and don'ts:
|
ERROR:
|
A white space character in quoted or block scalar content:
|
In the examples, tab characters are displayed as the glyph “→”. Space characters are sometimes displayed as the glyph “·” for clarity.
Example 4.13. Tabs and Spaces
··"Text·containing···
Legend: #x9 (TAB) #x20 (SP) |
%YAML 1.1
|
An ignored white space character inside scalar content:
|
A non space (and non-break) character:
|
A decimal digit for numbers:
|
A hexadecimal digit for escape sequences:
|
An ASCII letter (alphabetic) character:
|
A word (alphanumeric) character for identifiers:
|
A URI character for tags, as specified in RFC2396 with the addition of the “[” and “]” for presenting IPv6 addresses as proposed in RFC2732. A limited form of 8-bit escaping is available using the “%” character. By convention, URIs containing 16 and 32 bit Unicode characters are encoded in UTF-8, and then each octet is written as a separate character.
|
The “!” character is used to indicate the end of a named tag handle; hence its use in tag shorthands is restricted.
|
All non-printable characters must be presented as escape sequences. Each escape sequences must be parsed into the appropriate Unicode character. The original escape sequence form is a presentation detail and must not be used to convey content information. YAML escape sequences use the “\” notation common to most modern computer languages. Note that escape sequences are only interpreted in double quoted scalars. In all other scalar styles, the “\” character has no special meaning and non-printable characters are not available.
|
YAML escape sequences are a superset of C's escape sequences:
Escaped ASCII null (#x0) character:
|
Escaped ASCII bell (#x7) character:
|
Escaped ASCII backspace (#x8) character:
|
Escaped ASCII horizontal tab (#x9) character:
|
Escaped ASCII line feed (#xA) character:
|
Escaped ASCII vertical tab (#xB) character:
|
Escaped ASCII form feed (#xC) character:
|
Escaped ASCII carriage return (#xD) character:
|
Escaped ASCII escape (#x1B) character:
|
Escaped ASCII space (#x20) character:
|
Escaped ASCII double quote (“"”):
|
Escaped ASCII back slash (“\”):
|
Escaped Unicode next line (#x85) character:
|
Escaped Unicode non-breaking space (#xA0) character:
|
Escaped Unicode line separator (#x2028) character:
|
Escaped Unicode paragraph separator (#x2029) character:
|
Escaped 8-bit Unicode character:
|
Escaped 16-bit Unicode character:
|
Escaped 32-bit Unicode character:
|
Any escaped character:
Example 4.14. Escaped Characters
"Fun with \\
Legend: ns-esc-char |
%YAML 1.1
|
As YAML's syntax is designed for maximal readability, it makes heavy use of the context that each syntactical entity appears in. For notational compactness, this is expressed using parameterized BNF productions. The set of parameters and the range of allowed values depend on the specific production. The full list of possible parameters and their values is:
Since the character stream depends upon indentation level to delineate blocks, many productions are parameterized by it. In some cases, the notations “production(<n)”, “production(≤n)” and “production(>n)” are used; these are shorthands for “production(m)” for some specific m where 0 ≤ m < n, 0 ≤ m ≤ n and m > n, respectively.
YAML supports two groups of contexts, distinguishing between block styles and flow styles. In the block styles, indentation is used to delineate structure. Due to the fact that the “-” character denoting a block sequence entry is perceived as an indentation character, some productions distinguish between the block-in context (inside a block sequence) and the block-out context (outside one). In the flow styles, explicit indicators are used to delineate structure. As plain scalars have no such indicators, they are the most context sensitive, distinguishing between being nested inside a flow collection (flow-in context) or being outside one (flow-out context). YAML also provides a terse and intuitive syntax for simple keys. Plain scalars in this (flow-key) context are the most restricted, for readability and implementation reasons.
Scalar content may be presented in one of five styles: the plain, double quoted and single quoted flow styles, and the literal and folded block styles.
Block scalars offer three possible mechanisms for chomping any trailing line breaks: strip, clip and keep.
In a YAML character stream, structure is often determined from indentation, where indentation is defined as a line break character (or the start of the stream) followed by zero or more space characters. Note that indentation must not contain any tab characters. The amount of indentation is a presentation detail used exclusively to delineate structure and is otherwise ignored. In particular, indentation characters must never be considered part of a node's content information.
|
Example 4.16. Indentation Spaces
··# Leading comment line spaces are
Legend: s-indent(n) Content Neither content nor indentation |
%YAML 1.1
|
In general, a 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. The “-”, “?” and “:” characters used to denote block collection entries are perceived by people to be part of the indentation. Hence the indentation rules are slightly more flexible when dealing with these indicators. First, a block sequence need not be indented relative to its parent node, unless that node is also a block sequence. Second, compact in-line notations allow a nested collection to begin immediately following the indicator (where the indicator is counted as part of the indentation). This provides for an intuitive collection nesting syntax.
An explicit comment is is marked by a “#” indicator. Comments are a presentation detail and must have no effect on the serialization tree (and hence the representation graph).
|
Comments always span to the end of the line.
|
Outside scalar content, comments may appear on a line of their own, independent of the indentation level. Note that tab characters must not be used and that empty lines outside scalar content are taken to be (empty) comment lines.
|
Example 4.17. Comment Lines
··# Comment↓
|
# This stream contains no
Legend: c-b-comment l-comment |
When a comment follows another syntax element, it must be separated from it by space characters. Like the comment itself, such characters are not considered part of the content information.
|
Example 4.18. Comments Ending a Line
key:····# Comment↓
Legend: c-nb-comment-text s-b-comment |
%YAML 1.1
|
In most cases, when a line may end with a comment, YAML allows it to be followed by additional comment lines.
|
Example 4.19. Multi-Line Comments
key:····# Comment↓
Legend: s-b-comment l-comment s-l-comments |
%YAML 1.1
|
Outside scalar content, YAML uses space characters for separation between tokens. Note that separation must not contain tab characters. Seperation spaces are a presentation detail used exclusively to delineate structure and are otherwise ignored; in particular, such characters must never be considered part of a node's content information.
|
|
Inside simple keys, however, separation spaces are confined to the current line.
|
Example 4.20. Separation Spaces
{·first:·Sammy,·last:·Sosa·}:↓
Legend: s-separate-spaces s-separate-lines(n) s-indent(n) |
%YAML 1.1
|
YAML discards the “empty” prefix of each scalar content line. This prefix always includes the indentation, and depending on the scalar style may also include all leading white space. The ignored prefix is a presentation detail and must never be considered part of a node's content information.
|
Plain scalars must not contain any tab characters, and all leading spaces are always discarded.
|
Quoted scalars may contain tab characters. Again, all leading white space is always discarded.
|
Block scalars rely on indentation; hence leading white space, if any, is not discarded.
|
Example 4.21. Ignored Prefix
plain: text
Legend: s-ignored-prefix-plain(n) s-ignored-prefix-quoted(n) s-ignored-prefix-block(n) s-indent(n) |
%YAML 1.1
|
An empty line line consists of the ignored prefix followed by a line break. When trailing block scalars, such lines can also be interpreted as (empty) comment lines. YAML provides a chomping mechanism to resolve this ambiguity.
|
Example 4.22. Empty Lines
- foo
·↓
bar
- |-
foo
·↓
bar
··↓
|
%YAML 1.1
Legend: l-empty(n,s) l-comment |
Line folding allows long lines to be broken for readability, while retaining the original semantics of a single long line. When folding is done, any line break ending an empty line is preserved. In addition, any specific line breaks are also preserved, even when ending a non-empty line.
|
Hence, folding only applies to generic line breaks that end non-empty lines. If the following line is also not empty, the generic line break is converted to a single space (#x20).
|
If the following line is empty line, the generic line break is ignored.
|
Thus, a folded non-empty line may end with one of three possible folded line break forms. The original form of such a folded line break is a presentation detail and must not be used to convey node's content information.
|
Example 4.23. Line Folding
>-
|
%YAML 1.1
Legend: b-l-folded-specific(n,s) b-l-folded-as-space b-l-folded-trimmed(n,s) |
The above rules are common to both the folded block style and the scalar flow styles. Folding does distinguish between the folded block style and the scalar flow styles in the following way:
In the folded block style, folding does not apply to line breaks or empty lines that preced or follow a text line containing leading white space. Note that such a line may consist of only such leading white space; an empty block line is confined to (optional) indentation spaces only. Further, the final line break and empty lines are subject to chomping, and are never folded. The combined effect of these rules is that each “paragraph” is interpreted as a line, empty lines are used to present a line feed, the formatting of “more indented” lines is preserved, and final line breaks may be included or excluded from the node's content information as appropriate.
Folding in flow styles provides more relaxed, less powerful semantics. Flow styles typically depend on explicit indicators to convey structure, rather than indentation. Hence, in flow styles, spaces preceding or following the text in a line are a presentation detail and must not be considered a part of the node's content information. Once all such spaces have been discarded, folding proceeds as described above. In contrast with the block folded style, all line breaks are folded, without exception, and a line consisting only of spaces is considered to be an empty line, regardless of the number of spaces. The combined effect of these processing rules is that each “paragraph” is interpreted as a line, empty lines are used to present a line feed, and text can be freely “more indented” without affecting the node's content information.
A YAML character stream may contain several YAML documents, denoted by document boundary markers. Each document presents a single independent root node and may be preceded by a series of directives.
Directives are instructions to the YAML processor. Like comments, directives are presentation details and are not reflected in the serialization tree (and hence the representation graph). This specification defines two directives, “YAML” and “TAG”, and reserves all other directives for future use. There is no way to define private directives. This is intentional.
|
Each directive is specified on a separate non-indented line starting with the “%” indicator, followed by the directive name and a space-separated list of parameters. The semantics of these tokens depend on the specific directive. A YAML processor should ignore unknown directives with an appropriate warning.
|
Example 4.24. Reserved Directives
%FOO bar baz # Should be ignored
|
%YAML 1.1
Legend: l-reserved-directive ns-directive-name ns-directive-parameter |
The “YAML” directive specifies the version of YAML the document adheres to. This specification defines version “1.1”. A version 1.1 YAML processor should accept documents with an explicit “%YAML 1.1” directive, as well as documents lacking a “YAML” directive. Documents with a “YAML” directive specifying a higher minor version (e.g. “%YAML 1.2”) should be processed with an appropriate warning. Documents with a “YAML” directive specifying a higher major version (e.g. “%YAML 2.0”) should be rejected with an appropriate error message.
|
Example 4.25. “YAML” directive
%YAML 1.2 # Attempt parsing
|
%YAML 1.1
Legend: l-yaml-directive ns-yaml-version |
It is an error to specify more than one “YAML” directive for the same document, even if both occurences give the same version number.
The “TAG” directive establishes a shorthand notation for specifying node tags. Each “TAG” directive associates a handle with a prefix, allowing for compact and readable tag notation.
|
Example 4.27. “TAG” directive
%TAG !yaml! tag:yaml.org,2002:↓
|
%YAML 1.1
Legend: l-tag-directive c-tag-handle ns-tag-prefix |
It is an error to specify more than one “TAG” directive for the same handle in the same document, even if both occurences give the same prefix.
Example 4.28. Invalid Repeated TAG directive
%TAG ! !foo
|
ERROR:
|
There are two tag prefix variants:
|
If the prefix begins with a “!” character, shorthands using the handle are expanded to a local tag beginning with “!”. Note that such a tag is intentionally not a valid URI, since its semantics are specific to the application. In particular, two documents in the same stream may assign different semantics to the same local tag.
|
If the prefix begins with a character other than “!”, it must to be a valid URI prefix, and should contain at least the scheme and the authority. Shorthands using the associated handle are expanded to globally unique URI tags, and their semantics is consistent across applications. In particular, two documents in different streams must assign the same semantics to the same global tag.
|
Example 4.29. Tag Prefixes
%TAG ! !foo
Legend: ns-local-tag-prefix ns-global-tag-prefix |
%YAML 1.1
|
The tag handle exactly matches the prefix of the affected shorthand. There are three tag handle variants:
|
The primary tag handle is a single “!” character. This allows using the most compact possible notation for a single “primary” name space. By default, the prefix associated with this handle is “!”. Thus, by default, shorthands using this handle are interpreted as local tags. It is possible to override this behavior by providing an explicit “TAG” directive associating a different prefix for this handle. This provides smooth migration from using local tags to using global tags by a simple addition of a single “TAG” directive.
|
Example 4.30. Migrating from Local to Global Tags
# Private application:
# Migrated to global:
|
%YAML 1.1
%YAML 1.1
|
The secondary tag handle is written as “!!”. This allows using a compact notation for a single “secondary” name space. By default, the prefix associated with this handle is “tag:yaml.org,2002:” used by the YAML tag repository providing recommended tags for increasing the portability of YAML documents between different applications. It is possible to override this behavior by providing an explicit “TAG” directive associating a different prefix for this handle.
|
A named tag handle surrounds the non-empty name with “!” characters. A handle name must only be used in a shorthand if an explicit “TAG” directive has associated some prefix with it. The name of the handle is a presentation detail and is not part of the node's content information. In particular, the YAML processor need not preserve the handle name once parsing is completed.
|
Example 4.31. Tag Handles
# Explicitly specify default settings:
|
%YAML 1.1
Legend: c-primary-tag-handle c-secondary-tag-handle c-named-tag-handle |
YAML streams use document boundary markers to allow more than one document to be contained in the same stream. Such markers are a presentation detail and are used exclusively to convey structure. A line beginning with “---” may be used to explicitly denote the beginning of a new YAML document.
|
When YAML is used as the format of a communication channel, it is useful to be able to indicate the end of a document without closing the stream, independent of starting the next document. Lacking such a marker, the YAML processor reading the stream would be forced to wait for the header of the next document (that may be long time in coming) in order to detect the end of the previous one. To support this scenario, a YAML document may be terminated by an explicit end line denoted by “...”, followed by optional comments. To ease the task of concatenating YAML streams, the end marker may be repeated.
|
Example 4.32. Document Boundary Markers
---↓
|
%YAML 1.1
Legend: c-document-start l-document-suffix |
A YAML document is a single native data structure presented as a single root node. Presentation details such as directives, comments, indentation and styles are not considered part of the content information of the document.
An explicit document begins with a document start marker followed by the presentation of the root node. The node may begin in the same line as the document start marker. If the explicit document's node is completely empty, it is assumed to be an empty plain scalar with no specified properties. Optional document end marker(s) may follow the document.
|
An implicit document does not begin with a document start marker. In this case, the root node must not be presented as a completely empty node. Again, optional document end marker(s) may follow the document.
|
In general, the document's node is indented as if it has a parent indented at -1 spaces. Since a node must be more indented that its parent node, this allows the document's node to be indented at zero or more spaces. Note that flow scalar continuation lines must be indented by at least one space, even if their first line is not indented.
Example 4.33. Documents
"Root flow
Legend: l-implicit-document l-explicit-document |
%YAML 1.1
|
A sequence of bytes is a YAML character stream if, taken as a whole, it complies with the l-yaml-stream production. The stream begins with a prefix containing an optional byte order mark denoting its character encoding, followed by optional comments. Note that the stream may contain no documents, even if it contains a non-empty prefix. In particular, a stream containing no chareacters is valid and contains no documents.
|
Example 4.34. Empty Stream
⇔# A stream may contain
Legend: l-yaml-stream |
# This stream contains no
|
The first document may be implicit (omit the document start marker). In such a case it must not specify any directives and will be parsed using the default settings. If the document is explicit (begins with an document start marker), it may specify directives to control its parsing.
|
Example 4.35. First Document
# Implicit document. Root
# Explicit document. Root
Legend: l-first-document |
%YAML 1.1
%YAML 1.1
|
To ease the task of concatenating character streams, following documents may begin with a byte order mark and comments, though the same character encoding must be used through the stream. Each following document must be explicit (begin with a document start marker). If the document specifies no directives, it is parsed using the same settings as the previous document. If the document does specify any directives, all directives of previous documents, if any, are ignored.
|
Example 4.36. Next Documents
! "First document"
|
%YAML 1.1
Legend: l-next-document |
Each presentation node may have two optional properties, anchor and tag, in addition to its content. Node properties may be specified in any order before the node's content, and either or both may be omitted from the character stream.
|
Example 4.37. Node Properties
!!str
Legend: c-ns-anchor-property c-ns-tag-property c-ns-properties(n,c) |
%YAML 1.1
|
The anchor property marks a node for future reference. An anchor is denoted by the “&” indicator. An alias node can then be used to indicate additional inclusions of the anchored node by specifying its anchor. An anchored node need not be referenced by any alias node; in particular, it is valid for all nodes to be anchored.
|
Note that as a serialization detail, the anchor name is preserved in the serialization tree. However, it is not reflected in the representation graph and must not be used to convey content information. In particular, the YAML processor need not preserve the anchor name once the representation is composed.
|
Example 4.38. Node Anchors
First occurence: &anchor Value
Legend: c-ns-anchor-property ns-anchor-name |
%YAML 1.1
|
The tag property identifies the type of the native data structure presented by the node. A tag is denoted by the “!” indicator. In contrast with anchors, tags are an inherent part of the representation graph.
|
A tag may be written verbatim by surrounding it with the “<” and “>” characters. In this case, the YAML processor must deliver the verbatim tag as-is to the application. In particular, verbatim tags are not subject to tag resolution. A verbatim tag must either begin with a “!” (a local tag) or be a valid URI (a global tag).
|
Example 4.39. Verbatim Tags
!<tag:yaml.org,2002:str> foo :
Legend: c-verbatim-tag |
%YAML 1.1
|
Example 4.40. Invalid Verbatim Tags
- !<!> foo
|
ERROR:
|
A tag shorthand consists of a valid tag handle followed by a non-empty suffix. The tag handle must be associated with a prefix, either by default or by using a “TAG” directive. The resulting parsed tag is the concatenation of the prefix and the suffix, and must either begin with “!” (a local tag) or be a valid URI (a global tag). When the primary tag handle is used, the suffix must not contain any “!” character, as this would cause the tag shorthand to be interpreted as having a named tag handle. If the “!” character exists in the suffix of a tag using the primary tag handle, it must be escaped as “%21”, and the parser should expand this particular escape sequence before passing the tag to the application. This behavior is consistent with the URI character quoting rules (specifically, section 2.3 of RFC2396), and ensures the choice of tag handle remains a presentation detail and is not reflected in the serialization tree (and hence the representation graph). In particular, the tag handle may be discarded once parsing is completed.
|
Example 4.41. Tag Shorthands
%TAG !o! tag:ben-kiki.org,2000:
Legend: c-ns-shorthand-tag |
%YAML 1.1
|
Example 4.42. Invalid Shorthand Tags
%TAG !o! tag:ben-kiki.org,2000:
|
ERROR:
|
If a node has no tag property, it is assigned a non-specific tag: “?” for plain scalars and “!” for all other nodes. Non-specific tags must be resolved to a specific tag for a complete representation graph to be composed. It is also possible for the tag property to explicitly specify the node has the “!” non-specific tag. This is only useful for plain scalars, causing them to be resolved as if they were non-plain (hence, by the common tag resolution convention, as “tag:yaml.org,2002:str”). There is no way to explicitly set the tag to the “?” non-specific tag. This is intentional.
|
Example 4.43. Non-Specific Tags
# Assuming conventional resolution:
Legend: c-ns-non-specific-tag |
%YAML 1.1
|
Node content may be presented in either a flow style or a block style. Block content always extends to the end of a line and uses indentation to denote structure, while flow content starts and ends at some non-space character within a line and uses indicators to denote structure. Each collection kind can be presented in a single flow collection style or a single block collection style. However, each collection kind also provides compact in-line forms for common cases. Scalar content may be presented in the plain style or one of the two quoted styles (the single quoted style and the double quoted style). Regardless of style, scalar content must always be indented by at least one space. In contrast, collection content need not be indented (note that the indentation of the first flow scalar line is determined by the block collection it is nested in, if any).
|
Example 4.44. Mandatory Scalar Indentation
---
Legend: Normal "more-indented" indentation Mandatory for "non-indented" scalar |
%YAML 1.1
|
Example 4.45. Flow Content
---
Legend: ns-flow-scalar c-flow-collection not content |
%YAML 1.1
|
Example 4.46. Block Content
block styles:
Legend: c-l+block-scalar c-l-block-collection not content |
%YAML 1.1
|
Subsequent occurrences of a previously serialized node are presented as alias nodes, denoted by the “*” indicator. The first occurrence of the node must be marked by an anchor to allow subsequent occurrences to be presented as alias nodes. An alias node refers to the most recent preceding node having the same anchor. It is an error to have an alias node use an anchor that does not previously occur in the document. It is not an error to specify an anchor that is not used by any alias node. Note that an alias node must not specify any properties or content, as these were already specified at the first occurrence of the node.
|
Example 4.47. Alias Nodes
First occurence: &anchor Value
Legend: c-ns-alias-node ns-anchor-name |
%YAML 1.1
|
A complete flow node is either an alias node presenting a second occurence of a previous node, or consists of the node properties followed by the node's content. A node with empty content is considered to be an empty plain scalar.
|
Example 4.48. Flow Nodes in Flow Context
[
Legend: ns-flow-node(n,c) ns-flow-content(n,c) |
%YAML 1.1
|
Since both the node's properties and node content are optional, this allows for a completely empty node. Completely empty nodes are only valid when following some explicit indicator for their existance.
|
In the examples, completely empty nodes are displayed as the glyph “°”. Note that this glyph corresponds to a position in the characters stream rather than to an actual character.
Example 4.49. Completely Empty Flow Nodes
{
Legend: e-empty-flow |
%YAML 1.1
|
A complete block node consists of the node's properties followed by the node's content. In addition, a block node may consist of a (possibly completely empty) flow node followed by a line break (with optional comments).
|
Example 4.50. Block Nodes
-·"flow in block"↓
Legend: ns-l+flow-in-block(n,c) ns-l+block-in-block(n,c) s-l+block-node(n,c) |
%YAML 1.1
|
A block node always spans to the end of the line, even when completely empty. Completely empty block nodes may only appear when there is some explicit indicator for their existance.
|
Example 4.51. Completely Empty Block Nodes
seq:
Legend: s-l-empty-block |
%YAML 1.1
|
YAML provides a rich set of scalar styles to choose from, depending upon the readability requirements: three scalar flow styles (the plain style and the two quoted styles: single quoted and double quoted), and two scalar block styles (the literal style and the folded style). Comments may precede or follow scalar content, but must not appear inside it. Scalar node style is a presentation detail and must not be used to convey content information, with the exception that untagged plain scalars are resolved in a distinct way.
All flow scalar styles may span multiple lines, except when used in simple keys. Flow scalars are subject to (flow) line folding. This allows flow scalar content to be broken anywhere a single space character (#x20) separates non-space characters, at the cost of requiring an empty line to present each line feed character.
The double quoted style is specified by surrounding “"” indicators. This is the only scalar style capable of expressing arbitrary strings, by using “\” escape sequences. Therefore, the “\” and “"” characters must also be escaped when present in double quoted content. Note it is an error for double quoted content to contain invalid escape sequences.
|
Double quoted scalars are restricted to a single line when contained inside a simple key.
|
Example 4.52. Double Quoted Scalars
"simple key" : {
Legend: nb-double-single nb-double-multi(n) c-double-quoted(n,c) |
%YAML 1.1
|
A single line double quoted scalar is a sequence of (possibly escaped) non-break Unicode characters. All characters are considered content, including any leading or trailing white space characters.
|
In a multi-line double quoted scalar, line breaks are subject to flow line folding, and any trailing white space is excluded from the content. However, an escaped line break (using a “\”) is excluded from the content, while white space preceding it is preserved. This allows double quoted content to be broken at arbitrary positions.
|
Example 4.53. Double Quoted Line Breaks
"as space→↓
|
%YAML 1.1
Legend: s-l-double-folded(n) s-l-double-escaped(n) s-ignored-white s-white (Content) |
A multi-line double quoted scalar consists of a (possibly empty) first line, any number of inner lines, and a final (possibly empty) last line.
|
Leading white space in the first line is considered content only if followed by a non-space character or an escaped (ignored) line break.
|
Example 4.54. First Double Quoted Line
- "↓
Legend: nb-l-double-first(n) s-ignored-white |
%YAML 1.1
|
All leading and trailing white space of an inner lines are excluded from the content. Note that such while prefix white space may contain tab characters, line indentation is restricted to space characters only. It is possible to force considering leading white space as content by escaping the first character (“\·”, “\→” or “\t”).
|
Example 4.55. Inner Double Quoted Lines
"first
Legend: l-double-inner(n) s-ignored-prefix(n,s) s-l-double-break(n) |
%YAML 1.1
|
The leading prefix white space of the last line is stripped in the same way as for inner lines. Trailing white space is considered content only if preceded by a non-space character.
|
Example 4.56. Last Double Quoted Line
- "first
|
%YAML 1.1
Legend: s-nb-double-last(n) s-ignored-prefix(n,s) |
The single quoted style is specified by surrounding “'” indicators. Therefore, within a single quoted scalar such characters need to be repeated. This is the only form of escaping performed in single quoted scalars. In particular, the “\” and “"” characters may be freely used. This restricts single quoted scalars to printable characters.
|
Example 4.57. Single Quoted Quotes
'here''s to "quotes"'
Legend: single-quoted-quote |
%YAML 1.1
|
Single quoted scalars are restricted to a single line when contained inside a simple key.
|
Example 4.58. Single Quoted Scalars
'simple key' : {
Legend: nb-single-single nb-single-multi(n) c-single-quoted(n,c) |
%YAML 1.1
|
A single line single quoted scalar is a sequence of non-break printable characters. All characters are considered content, including any leading or trailing white space characters.
|
In a multi-line single quoted scalar, line breaks are subject to (flow) line folding, and any trailing white space is excluded from the content.
|
Example 4.59. Single Quoted Line Breaks
'as space→↓
|
%YAML 1.1
Legend: s-l-single-break(n) s-ignored-white s-white (Content) |
A multi-line single quoted scalar consists of a (possibly empty) first line, any number of inner lines, and a final (possibly empty) last line.
|
Leading white space in the first line is considered content only if followed by a non-space character.
|
Example 4.60. First Single Quoted Line
- '↓
Legend: nb-l-single-first(n) s-ignored-white |
%YAML 1.1
|
All leading and trailing white space of inner lines is excludced from the content. Note that while prefix white space may contain tab characters, line indentation is restricted to space characters only. Unlike double quoted scalars, it is impossible to force the inclusion of the leading or trailing spaces in the content. Therefore, single quoted scalars lines can only be broken where a single space character separates two non-space characters.
|
Example 4.61. Inner Single Quoted Lines
'first
Legend: l-single-inner(n) s-ignored-prefix(n,s) s-l-single-break(n) |
%YAML 1.1
|
The leading prefix white space of the last line is stripped in the same way as for inner lines. Trailing white space is considered content only if preceded by a non-space character.
|
Example 4.62. Last Single Quoted Lines
- 'first
Legend: s-nb-double-last(n) s-ignored-prefix(n,s) |
%YAML 1.1
|
The plain style uses no identifying indicators, and is therefore the most most limited and most context sen