yamlet
Safe HaskellNone
LanguageGHC2021

Yamlet.Syntax

Description

The representation of a YAML stream that keeps every detail of the presentation: the styles of scalars and collections, the lines of scalars, anchors, aliases, unresolved tags, comments and empty lines. The FromYaml and ToYaml classes read and write the nodes of this tree.

Most texts in the tree share the memory of the input, so a node keeps the whole input alive. To keep a text longer than the tree, copy it with copy, or copy the whole tree with copyDocument. Copy only what the program keeps: a copy of a whole tree usually needs more memory than the input it frees.

A document that the renderer writes back keeps its comments, empty lines and styles:

>>> input = "# The server.\nhost: localhost # only local\n\nports: [80, 443]\n"
>>> :{
case parseDocumentsText input of
  Left err -> putStrLn (prettyError "input.yaml" err)
  Right docs -> T.putStr (renderSyntax defaultRenderOptions docs)
:}
# The server.
host: localhost # only local

ports: [80, 443]

The section Comments gives the rules that decide the node of each comment.

Synopsis

Parsing

parseDocuments :: ByteString -> Either Error [Document] Source #

Parse the documents of a stream. The encoding is UTF-8, UTF-16 or UTF-32, detected as the YAML specification describes.

errorAt and decodeDocument need the text of the input. To report errors with the lines of the input, decode the input with decodeInput and parse it with parseDocumentsText.

parseDocumentsText :: Text -> Either Error [Document] Source #

Parse the documents of a stream.

>>> length <$> parseDocumentsText "a\n---\nb\n"
Right 2

decodeInput :: ByteString -> Either Error Text Source #

Decode the bytes of a stream to text. The encoding is UTF-8, UTF-16 or UTF-32, detected as the YAML specification describes.

copyDocument :: Document -> Document Source #

Copy every text of a document, so that the document does not keep the input alive.

copyNode :: Node -> Node Source #

Copy every text of a node, so that the node does not keep the input alive.

Rendering

renderSyntax :: RenderOptions -> [Document] -> Text Source #

Render documents with their comments and empty lines.

The output differs from the tree where YAML cannot hold it:

  • A --- marker is on a line of its own, with at most a comment after it.
  • A scalar keeps its style if the style can hold its text, otherwise it gets quotes. A block scalar that is a key or an entry of a flow collection gets double quotes. A block scalar at the root gets quotes in a few more cases, e.g. if its text starts with a space.
  • The empty lines from the comments right after a block scalar with the + indicator go away, because they would become part of the scalar.
  • A flow collection with comments inside becomes a block collection, so that every comment has a line.
  • A flow collection without comments is on one line, apart from the line breaks of its multi-line scalars, so the empty lines between its entries go away.
  • A key of more than 1024 characters in a flow mapping becomes an explicit key, e.g. {? key : value}, because YAML 1.1 parsers reject a longer implicit key there too.
  • A comment that has no place at its node moves to a place that has one, e.g. the lines above the value of a key go above the key if the value is on the line of the key.
  • In the text of a comment, a character that YAML does not allow becomes U+FFFD, and the white space at the end goes away. A line break starts a new comment in a CommentLine, and becomes a space in an inline comment.
  • An anchor name with a character that YAML does not allow in it, e.g. a space, or that YAML 1.1 parsers read as the end of the name, e.g. : or a line separator, becomes a new name in the anchor and in its aliases. Names that only some parsers reject stay, e.g. é, which libyaml rejects.
  • A version that the parser does not support, e.g. 2.0, has no %YAML directive.

With forceBlock, the flow collections become block collections:

>>> :{
case parseDocumentsText "a: [1, {b: 2}]\n" of
  Left err -> putStrLn (prettyError "input.yaml" err)
  Right docs ->
    T.putStr (renderSyntax defaultRenderOptions {forceBlock = True} docs)
:}
a:
- 1
- b: 2

data RenderOptions Source #

The options of renderSyntax.

Constructors

RenderOptions 

Fields

  • forceBlock :: !Bool

    Write every non-empty collection in the block style. A collection in a key then becomes an explicit key, e.g. ? - a.

Instances

Instances details
Generic RenderOptions Source # 
Instance details

Defined in Yamlet.Internal.Render

Associated Types

type Rep RenderOptions 
Instance details

Defined in Yamlet.Internal.Render

type Rep RenderOptions = D1 ('MetaData "RenderOptions" "Yamlet.Internal.Render" "yamlet-1.0.0.1-2nRkbEnNUrLFBALTocq2AS" 'False) (C1 ('MetaCons "RenderOptions" 'PrefixI 'True) (S1 ('MetaSel ('Just "forceBlock") 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 Bool)))
Show RenderOptions Source # 
Instance details

Defined in Yamlet.Internal.Render

Methods

showsPrec :: Int -> RenderOptions -> ShowS

show :: RenderOptions -> String

showList :: [RenderOptions] -> ShowS

Eq RenderOptions Source # 
Instance details

Defined in Yamlet.Internal.Render

type Rep RenderOptions Source # 
Instance details

Defined in Yamlet.Internal.Render

type Rep RenderOptions = D1 ('MetaData "RenderOptions" "Yamlet.Internal.Render" "yamlet-1.0.0.1-2nRkbEnNUrLFBALTocq2AS" 'False) (C1 ('MetaCons "RenderOptions" 'PrefixI 'True) (S1 ('MetaSel ('Just "forceBlock") 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 Bool)))

defaultRenderOptions :: RenderOptions Source #

Keep the collection styles of the tree.

Documents

data Document Source #

A document of a YAML stream.

Constructors

Document 

Fields

  • version :: !(Maybe YamlVersion)

    The version from the %YAML directive.

  • explicitStart :: !Bool

    The document starts with a --- marker.

  • explicitEnd :: !Bool

    The document ends with a ... marker.

  • docComments :: !Comments

    The lines before the directives or the --- marker, the comment on the line of the marker and the lines at the end of the document: below the ... marker, or below a flow collection root.

  • root :: !Node
     

Instances

Instances details
NFData Document Source # 
Instance details

Defined in Yamlet.Internal.Syntax

Methods

rnf :: Document -> ()

Generic Document Source # 
Instance details

Defined in Yamlet.Internal.Syntax

Associated Types

type Rep Document 
Instance details

Defined in Yamlet.Internal.Syntax

type Rep Document = D1 ('MetaData "Document" "Yamlet.Internal.Syntax" "yamlet-1.0.0.1-2nRkbEnNUrLFBALTocq2AS" 'False) (C1 ('MetaCons "Document" 'PrefixI 'True) ((S1 ('MetaSel ('Just "version") 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 (Maybe YamlVersion)) :*: S1 ('MetaSel ('Just "explicitStart") 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 Bool)) :*: (S1 ('MetaSel ('Just "explicitEnd") 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 Bool) :*: (S1 ('MetaSel ('Just "docComments") 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 Comments) :*: S1 ('MetaSel ('Just "root") 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 Node)))))

Methods

from :: Document -> Rep Document x

to :: Rep Document x -> Document

Show Document Source # 
Instance details

Defined in Yamlet.Internal.Syntax

Methods

showsPrec :: Int -> Document -> ShowS

show :: Document -> String

showList :: [Document] -> ShowS

Eq Document Source # 
Instance details

Defined in Yamlet.Internal.Syntax

Methods

(==) :: Document -> Document -> Bool

(/=) :: Document -> Document -> Bool

type Rep Document Source # 
Instance details

Defined in Yamlet.Internal.Syntax

type Rep Document = D1 ('MetaData "Document" "Yamlet.Internal.Syntax" "yamlet-1.0.0.1-2nRkbEnNUrLFBALTocq2AS" 'False) (C1 ('MetaCons "Document" 'PrefixI 'True) ((S1 ('MetaSel ('Just "version") 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 (Maybe YamlVersion)) :*: S1 ('MetaSel ('Just "explicitStart") 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 Bool)) :*: (S1 ('MetaSel ('Just "explicitEnd") 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 Bool) :*: (S1 ('MetaSel ('Just "docComments") 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 Comments) :*: S1 ('MetaSel ('Just "root") 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 Node)))))

data YamlVersion Source #

The version of YAML that a document declares.

Constructors

YamlVersion 

Fields

Instances

Instances details
NFData YamlVersion Source # 
Instance details

Defined in Yamlet.Internal.Syntax

Methods

rnf :: YamlVersion -> ()

Generic YamlVersion Source # 
Instance details

Defined in Yamlet.Internal.Syntax

Associated Types

type Rep YamlVersion 
Instance details

Defined in Yamlet.Internal.Syntax

type Rep YamlVersion = D1 ('MetaData "YamlVersion" "Yamlet.Internal.Syntax" "yamlet-1.0.0.1-2nRkbEnNUrLFBALTocq2AS" 'False) (C1 ('MetaCons "YamlVersion" 'PrefixI 'True) (S1 ('MetaSel ('Just "major") 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 Int) :*: S1 ('MetaSel ('Just "minor") 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 Int)))

Methods

from :: YamlVersion -> Rep YamlVersion x

to :: Rep YamlVersion x -> YamlVersion

Show YamlVersion Source # 
Instance details

Defined in Yamlet.Internal.Syntax

Methods

showsPrec :: Int -> YamlVersion -> ShowS

show :: YamlVersion -> String

showList :: [YamlVersion] -> ShowS

Eq YamlVersion Source # 
Instance details

Defined in Yamlet.Internal.Syntax

Methods

(==) :: YamlVersion -> YamlVersion -> Bool

(/=) :: YamlVersion -> YamlVersion -> Bool

Ord YamlVersion Source # 
Instance details

Defined in Yamlet.Internal.Syntax

type Rep YamlVersion Source # 
Instance details

Defined in Yamlet.Internal.Syntax

type Rep YamlVersion = D1 ('MetaData "YamlVersion" "Yamlet.Internal.Syntax" "yamlet-1.0.0.1-2nRkbEnNUrLFBALTocq2AS" 'False) (C1 ('MetaCons "YamlVersion" 'PrefixI 'True) (S1 ('MetaSel ('Just "major") 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 Int) :*: S1 ('MetaSel ('Just "minor") 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 Int)))

document :: Node -> Document Source #

A document with the given root, without directives, markers and comments.

Nodes

data Node Source #

A node of a document.

Constructors

Node 

Fields

Instances

Instances details
NFData Node Source # 
Instance details

Defined in Yamlet.Internal.Syntax

Methods

rnf :: Node -> ()

Generic Node Source # 
Instance details

Defined in Yamlet.Internal.Syntax

Associated Types

type Rep Node 
Instance details

Defined in Yamlet.Internal.Syntax

type Rep Node = D1 ('MetaData "Node" "Yamlet.Internal.Syntax" "yamlet-1.0.0.1-2nRkbEnNUrLFBALTocq2AS" 'False) (C1 ('MetaCons "Node" 'PrefixI 'True) ((S1 ('MetaSel ('Just "offset") 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 Offset) :*: S1 ('MetaSel ('Just "endOffset") 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 Offset)) :*: (S1 ('MetaSel ('Just "props") 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 Props) :*: (S1 ('MetaSel ('Just "comments") 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 Comments) :*: S1 ('MetaSel ('Just "content") 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 Content)))))

Methods

from :: Node -> Rep Node x

to :: Rep Node x -> Node

Show Node Source # 
Instance details

Defined in Yamlet.Internal.Syntax

Methods

showsPrec :: Int -> Node -> ShowS

show :: Node -> String

showList :: [Node] -> ShowS

Eq Node Source # 
Instance details

Defined in Yamlet.Internal.Syntax

Methods

(==) :: Node -> Node -> Bool

(/=) :: Node -> Node -> Bool

FromYaml Node Source #

The node of the syntax tree, with its styles and comments, e.g. to write a part of a document back as it was written. An alias in the input gives a copy of the node that it refers to.

The texts of the node are copies, so that a small part of a document does not keep the whole input alive. For a whole document without a copy, use parseDocuments.

Instance details

Defined in Yamlet.Internal.FromYaml

ToYaml Node Source # 
Instance details

Defined in Yamlet.Internal.ToYaml

type Rep Node Source # 
Instance details

Defined in Yamlet.Internal.Syntax

type Rep Node = D1 ('MetaData "Node" "Yamlet.Internal.Syntax" "yamlet-1.0.0.1-2nRkbEnNUrLFBALTocq2AS" 'False) (C1 ('MetaCons "Node" 'PrefixI 'True) ((S1 ('MetaSel ('Just "offset") 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 Offset) :*: S1 ('MetaSel ('Just "endOffset") 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 Offset)) :*: (S1 ('MetaSel ('Just "props") 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 Props) :*: (S1 ('MetaSel ('Just "comments") 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 Comments) :*: S1 ('MetaSel ('Just "content") 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 Content)))))

data Content Source #

The content of a node.

Constructors

ScalarLinesContent !ScalarStyle !Text ![Int]

A scalar with the positions in its text where the source continues on a new line. A position counts the characters from the start of the text, and the positions are in ascending order. The parser gives them for the plain, quoted and folded styles, which join the lines of the source, so that the renderer can write the text on the same lines. The renderer ignores a position where the style of the output cannot start a new line and keep the text.

SequenceContent !CollectionStyle ![Node] 
MappingContent !CollectionStyle ![(Node, Node)] 
AliasContent !Text

An alias, with the name of its anchor. An alias has no properties.

Bundled Patterns

pattern ScalarContent :: ScalarStyle -> Text -> Content

A scalar without positions of new lines. As a pattern, it matches every scalar and ignores its positions.

Instances

Instances details
NFData Content Source # 
Instance details

Defined in Yamlet.Internal.Syntax

Methods

rnf :: Content -> ()

Generic Content Source # 
Instance details

Defined in Yamlet.Internal.Syntax

Associated Types

type Rep Content 
Instance details

Defined in Yamlet.Internal.Syntax

type Rep Content = D1 ('MetaData "Content" "Yamlet.Internal.Syntax" "yamlet-1.0.0.1-2nRkbEnNUrLFBALTocq2AS" 'False) ((C1 ('MetaCons "ScalarLinesContent" 'PrefixI 'False) (S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 ScalarStyle) :*: (S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 Text) :*: S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 [Int]))) :+: C1 ('MetaCons "SequenceContent" 'PrefixI 'False) (S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 CollectionStyle) :*: S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 [Node]))) :+: (C1 ('MetaCons "MappingContent" 'PrefixI 'False) (S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 CollectionStyle) :*: S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 [(Node, Node)])) :+: C1 ('MetaCons "AliasContent" 'PrefixI 'False) (S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 Text))))

Methods

from :: Content -> Rep Content x

to :: Rep Content x -> Content

Show Content Source # 
Instance details

Defined in Yamlet.Internal.Syntax

Methods

showsPrec :: Int -> Content -> ShowS

show :: Content -> String

showList :: [Content] -> ShowS

Eq Content Source # 
Instance details

Defined in Yamlet.Internal.Syntax

Methods

(==) :: Content -> Content -> Bool

(/=) :: Content -> Content -> Bool

type Rep Content Source # 
Instance details

Defined in Yamlet.Internal.Syntax

type Rep Content = D1 ('MetaData "Content" "Yamlet.Internal.Syntax" "yamlet-1.0.0.1-2nRkbEnNUrLFBALTocq2AS" 'False) ((C1 ('MetaCons "ScalarLinesContent" 'PrefixI 'False) (S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 ScalarStyle) :*: (S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 Text) :*: S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 [Int]))) :+: C1 ('MetaCons "SequenceContent" 'PrefixI 'False) (S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 CollectionStyle) :*: S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 [Node]))) :+: (C1 ('MetaCons "MappingContent" 'PrefixI 'False) (S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 CollectionStyle) :*: S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 [(Node, Node)])) :+: C1 ('MetaCons "AliasContent" 'PrefixI 'False) (S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 Text))))

data Props Source #

The properties of a node.

Constructors

Props 

Fields

Instances

Instances details
NFData Props Source # 
Instance details

Defined in Yamlet.Internal.Syntax

Methods

rnf :: Props -> ()

Generic Props Source # 
Instance details

Defined in Yamlet.Internal.Syntax

Associated Types

type Rep Props 
Instance details

Defined in Yamlet.Internal.Syntax

type Rep Props = D1 ('MetaData "Props" "Yamlet.Internal.Syntax" "yamlet-1.0.0.1-2nRkbEnNUrLFBALTocq2AS" 'False) (C1 ('MetaCons "Props" 'PrefixI 'True) (S1 ('MetaSel ('Just "anchor") 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 (Maybe Text)) :*: S1 ('MetaSel ('Just "tag") 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 Tag)))

Methods

from :: Props -> Rep Props x

to :: Rep Props x -> Props

Show Props Source # 
Instance details

Defined in Yamlet.Internal.Syntax

Methods

showsPrec :: Int -> Props -> ShowS

show :: Props -> String

showList :: [Props] -> ShowS

Eq Props Source # 
Instance details

Defined in Yamlet.Internal.Syntax

Methods

(==) :: Props -> Props -> Bool

(/=) :: Props -> Props -> Bool

type Rep Props Source # 
Instance details

Defined in Yamlet.Internal.Syntax

type Rep Props = D1 ('MetaData "Props" "Yamlet.Internal.Syntax" "yamlet-1.0.0.1-2nRkbEnNUrLFBALTocq2AS" 'False) (C1 ('MetaCons "Props" 'PrefixI 'True) (S1 ('MetaSel ('Just "anchor") 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 (Maybe Text)) :*: S1 ('MetaSel ('Just "tag") 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 Tag)))

noProps :: Props Source #

No anchor and no tag.

data Tag Source #

The tag of a node after the tag handles are expanded.

Constructors

NoTag

The node has no tag.

NonSpecificTag

The ! tag.

Tag !Text

A specific tag, e.g. tag:yaml.org,2002:str for !!str. YAML has no syntax for the empty tag or a tag of one character, e.g. x or !. The renderer writes such a tag as !, which reads back as NonSpecificTag.

Instances

Instances details
NFData Tag Source # 
Instance details

Defined in Yamlet.Internal.Syntax

Methods

rnf :: Tag -> ()

Generic Tag Source # 
Instance details

Defined in Yamlet.Internal.Syntax

Associated Types

type Rep Tag 
Instance details

Defined in Yamlet.Internal.Syntax

type Rep Tag = D1 ('MetaData "Tag" "Yamlet.Internal.Syntax" "yamlet-1.0.0.1-2nRkbEnNUrLFBALTocq2AS" 'False) (C1 ('MetaCons "NoTag" 'PrefixI 'False) (U1 :: Type -> Type) :+: (C1 ('MetaCons "NonSpecificTag" 'PrefixI 'False) (U1 :: Type -> Type) :+: C1 ('MetaCons "Tag" 'PrefixI 'False) (S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 Text))))

Methods

from :: Tag -> Rep Tag x

to :: Rep Tag x -> Tag

Show Tag Source # 
Instance details

Defined in Yamlet.Internal.Syntax

Methods

showsPrec :: Int -> Tag -> ShowS

show :: Tag -> String

showList :: [Tag] -> ShowS

Eq Tag Source # 
Instance details

Defined in Yamlet.Internal.Syntax

Methods

(==) :: Tag -> Tag -> Bool

(/=) :: Tag -> Tag -> Bool

Ord Tag Source # 
Instance details

Defined in Yamlet.Internal.Syntax

Methods

compare :: Tag -> Tag -> Ordering

(<) :: Tag -> Tag -> Bool

(<=) :: Tag -> Tag -> Bool

(>) :: Tag -> Tag -> Bool

(>=) :: Tag -> Tag -> Bool

max :: Tag -> Tag -> Tag

min :: Tag -> Tag -> Tag

type Rep Tag Source # 
Instance details

Defined in Yamlet.Internal.Syntax

type Rep Tag = D1 ('MetaData "Tag" "Yamlet.Internal.Syntax" "yamlet-1.0.0.1-2nRkbEnNUrLFBALTocq2AS" 'False) (C1 ('MetaCons "NoTag" 'PrefixI 'False) (U1 :: Type -> Type) :+: (C1 ('MetaCons "NonSpecificTag" 'PrefixI 'False) (U1 :: Type -> Type) :+: C1 ('MetaCons "Tag" 'PrefixI 'False) (S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 Text))))

data ScalarStyle Source #

The style of a scalar: without quotes, in single or double quotes, or a literal (|) or folded (>) block scalar.

Instances

Instances details
NFData ScalarStyle Source # 
Instance details

Defined in Yamlet.Internal.Syntax

Methods

rnf :: ScalarStyle -> ()

Bounded ScalarStyle Source # 
Instance details

Defined in Yamlet.Internal.Syntax

Enum ScalarStyle Source # 
Instance details

Defined in Yamlet.Internal.Syntax

Generic ScalarStyle Source # 
Instance details

Defined in Yamlet.Internal.Syntax

Associated Types

type Rep ScalarStyle 
Instance details

Defined in Yamlet.Internal.Syntax

type Rep ScalarStyle = D1 ('MetaData "ScalarStyle" "Yamlet.Internal.Syntax" "yamlet-1.0.0.1-2nRkbEnNUrLFBALTocq2AS" 'False) ((C1 ('MetaCons "Plain" 'PrefixI 'False) (U1 :: Type -> Type) :+: C1 ('MetaCons "SingleQuoted" 'PrefixI 'False) (U1 :: Type -> Type)) :+: (C1 ('MetaCons "DoubleQuoted" 'PrefixI 'False) (U1 :: Type -> Type) :+: (C1 ('MetaCons "Literal" 'PrefixI 'False) (U1 :: Type -> Type) :+: C1 ('MetaCons "Folded" 'PrefixI 'False) (U1 :: Type -> Type))))

Methods

from :: ScalarStyle -> Rep ScalarStyle x

to :: Rep ScalarStyle x -> ScalarStyle

Show ScalarStyle Source # 
Instance details

Defined in Yamlet.Internal.Syntax

Methods

showsPrec :: Int -> ScalarStyle -> ShowS

show :: ScalarStyle -> String

showList :: [ScalarStyle] -> ShowS

Eq ScalarStyle Source # 
Instance details

Defined in Yamlet.Internal.Syntax

Methods

(==) :: ScalarStyle -> ScalarStyle -> Bool

(/=) :: ScalarStyle -> ScalarStyle -> Bool

Ord ScalarStyle Source # 
Instance details

Defined in Yamlet.Internal.Syntax

type Rep ScalarStyle Source # 
Instance details

Defined in Yamlet.Internal.Syntax

type Rep ScalarStyle = D1 ('MetaData "ScalarStyle" "Yamlet.Internal.Syntax" "yamlet-1.0.0.1-2nRkbEnNUrLFBALTocq2AS" 'False) ((C1 ('MetaCons "Plain" 'PrefixI 'False) (U1 :: Type -> Type) :+: C1 ('MetaCons "SingleQuoted" 'PrefixI 'False) (U1 :: Type -> Type)) :+: (C1 ('MetaCons "DoubleQuoted" 'PrefixI 'False) (U1 :: Type -> Type) :+: (C1 ('MetaCons "Literal" 'PrefixI 'False) (U1 :: Type -> Type) :+: C1 ('MetaCons "Folded" 'PrefixI 'False) (U1 :: Type -> Type))))

data CollectionStyle Source #

The style of a collection: with indentation, or with brackets and commas.

Constructors

Block 
Flow 

Instances

Instances details
NFData CollectionStyle Source # 
Instance details

Defined in Yamlet.Internal.Syntax

Methods

rnf :: CollectionStyle -> ()

Bounded CollectionStyle Source # 
Instance details

Defined in Yamlet.Internal.Syntax

Enum CollectionStyle Source # 
Instance details

Defined in Yamlet.Internal.Syntax

Generic CollectionStyle Source # 
Instance details

Defined in Yamlet.Internal.Syntax

Associated Types

type Rep CollectionStyle 
Instance details

Defined in Yamlet.Internal.Syntax

type Rep CollectionStyle = D1 ('MetaData "CollectionStyle" "Yamlet.Internal.Syntax" "yamlet-1.0.0.1-2nRkbEnNUrLFBALTocq2AS" 'False) (C1 ('MetaCons "Block" 'PrefixI 'False) (U1 :: Type -> Type) :+: C1 ('MetaCons "Flow" 'PrefixI 'False) (U1 :: Type -> Type))
Show CollectionStyle Source # 
Instance details

Defined in Yamlet.Internal.Syntax

Methods

showsPrec :: Int -> CollectionStyle -> ShowS

show :: CollectionStyle -> String

showList :: [CollectionStyle] -> ShowS

Eq CollectionStyle Source # 
Instance details

Defined in Yamlet.Internal.Syntax

Ord CollectionStyle Source # 
Instance details

Defined in Yamlet.Internal.Syntax

type Rep CollectionStyle Source # 
Instance details

Defined in Yamlet.Internal.Syntax

type Rep CollectionStyle = D1 ('MetaData "CollectionStyle" "Yamlet.Internal.Syntax" "yamlet-1.0.0.1-2nRkbEnNUrLFBALTocq2AS" 'False) (C1 ('MetaCons "Block" 'PrefixI 'False) (U1 :: Type -> Type) :+: C1 ('MetaCons "Flow" 'PrefixI 'False) (U1 :: Type -> Type))

Construction

contentNode :: Content -> Node Source #

A node with the given content, without properties and comments.

scalarNode :: ScalarStyle -> Text -> Node Source #

A scalar in the given style. renderSyntax uses quotes if the style cannot hold the text, and for a block scalar that is a key or an entry of a flow collection.

>>> T.putStr (renderSyntax defaultRenderOptions [document (mappingNode [(plainNode "key", scalarNode Plain "a: b")])])
key: 'a: b'

plainNode :: Text -> Node Source #

A plain scalar.

foldedNode :: [Text] -> Node Source #

A folded block scalar (>-) with the given lines. The empty lines at the end are dropped, because >- strips them.

>>> T.putStr (renderSyntax defaultRenderOptions [document (mappingNode [(plainNode "options", foldedNode ["--health-cmd pg_isready", "--health-interval 5s"])])])
options: >-
  --health-cmd pg_isready
  --health-interval 5s

sequenceNode :: [Node] -> Node Source #

A block sequence.

mappingNode :: [(Node, Node)] -> Node Source #

A block mapping.

Positions

newtype Offset Source #

The offset of a byte in the input text, in its UTF-8 encoding. For an input in UTF-16 or UTF-32, the offset counts the bytes of the text after decodeInput, not the bytes of the input.

Constructors

Offset Int 

Instances

Instances details
NFData Offset Source # 
Instance details

Defined in Yamlet.Internal.Syntax

Methods

rnf :: Offset -> ()

Generic Offset Source # 
Instance details

Defined in Yamlet.Internal.Syntax

Associated Types

type Rep Offset 
Instance details

Defined in Yamlet.Internal.Syntax

type Rep Offset = D1 ('MetaData "Offset" "Yamlet.Internal.Syntax" "yamlet-1.0.0.1-2nRkbEnNUrLFBALTocq2AS" 'True) (C1 ('MetaCons "Offset" 'PrefixI 'False) (S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 Int)))

Methods

from :: Offset -> Rep Offset x

to :: Rep Offset x -> Offset

Show Offset Source # 
Instance details

Defined in Yamlet.Internal.Syntax

Methods

showsPrec :: Int -> Offset -> ShowS

show :: Offset -> String

showList :: [Offset] -> ShowS

Eq Offset Source # 
Instance details

Defined in Yamlet.Internal.Syntax

Methods

(==) :: Offset -> Offset -> Bool

(/=) :: Offset -> Offset -> Bool

Ord Offset Source # 
Instance details

Defined in Yamlet.Internal.Syntax

Methods

compare :: Offset -> Offset -> Ordering

(<) :: Offset -> Offset -> Bool

(<=) :: Offset -> Offset -> Bool

(>) :: Offset -> Offset -> Bool

(>=) :: Offset -> Offset -> Bool

max :: Offset -> Offset -> Offset

min :: Offset -> Offset -> Offset

type Rep Offset Source # 
Instance details

Defined in Yamlet.Internal.Syntax

type Rep Offset = D1 ('MetaData "Offset" "Yamlet.Internal.Syntax" "yamlet-1.0.0.1-2nRkbEnNUrLFBALTocq2AS" 'True) (C1 ('MetaCons "Offset" 'PrefixI 'False) (S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 Int)))

noOffset :: Offset Source #

The offset of a node that does not come from an input.

Comments

The parser gives each comment to one node or document, and the renderer writes it back at that place. A stream without documents, e.g. a stream of only comments, has no such place. The parser drops its comments.

In the examples below, printComments parses a text and prints each node that has comments, with its path and the fields of Comments. The key and the value of an entry have the same path, with (key) or (value) after it.

data Comments Source #

The comments and the empty lines that belong to a node.

Constructors

Comments 

Fields

  • before :: ![Line]

    The lines above the node.

  • inline :: !(Maybe Text)

    The comment at the end of the line where the node ends, or of the first line of a block collection or a block scalar. The renderer writes each line break in it as a space. The line breaks are the characters that CommentLine lists.

  • after :: ![Line]

    The lines below the node: after the last entry of a collection, between the brackets of an empty collection, or below a scalar or an alias in a block collection or at the root. The section Comments gives the rules. The renderer writes such lines below any node.

Instances

Instances details
NFData Comments Source # 
Instance details

Defined in Yamlet.Internal.Syntax

Methods

rnf :: Comments -> ()

Generic Comments Source # 
Instance details

Defined in Yamlet.Internal.Syntax

Associated Types

type Rep Comments 
Instance details

Defined in Yamlet.Internal.Syntax

type Rep Comments = D1 ('MetaData "Comments" "Yamlet.Internal.Syntax" "yamlet-1.0.0.1-2nRkbEnNUrLFBALTocq2AS" 'False) (C1 ('MetaCons "Comments" 'PrefixI 'True) (S1 ('MetaSel ('Just "before") 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 [Line]) :*: (S1 ('MetaSel ('Just "inline") 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 (Maybe Text)) :*: S1 ('MetaSel ('Just "after") 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 [Line]))))

Methods

from :: Comments -> Rep Comments x

to :: Rep Comments x -> Comments

Show Comments Source # 
Instance details

Defined in Yamlet.Internal.Syntax

Methods

showsPrec :: Int -> Comments -> ShowS

show :: Comments -> String

showList :: [Comments] -> ShowS

Eq Comments Source # 
Instance details

Defined in Yamlet.Internal.Syntax

Methods

(==) :: Comments -> Comments -> Bool

(/=) :: Comments -> Comments -> Bool

Ord Comments Source # 
Instance details

Defined in Yamlet.Internal.Syntax

Methods

compare :: Comments -> Comments -> Ordering

(<) :: Comments -> Comments -> Bool

(<=) :: Comments -> Comments -> Bool

(>) :: Comments -> Comments -> Bool

(>=) :: Comments -> Comments -> Bool

max :: Comments -> Comments -> Comments

min :: Comments -> Comments -> Comments

type Rep Comments Source # 
Instance details

Defined in Yamlet.Internal.Syntax

type Rep Comments = D1 ('MetaData "Comments" "Yamlet.Internal.Syntax" "yamlet-1.0.0.1-2nRkbEnNUrLFBALTocq2AS" 'False) (C1 ('MetaCons "Comments" 'PrefixI 'True) (S1 ('MetaSel ('Just "before") 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 [Line]) :*: (S1 ('MetaSel ('Just "inline") 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 (Maybe Text)) :*: S1 ('MetaSel ('Just "after") 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 [Line]))))

noComments :: Comments Source #

No comments and no empty lines.

withComments :: Comments -> Node -> Node Source #

The node with the comments in place of its own. A record update of the field is ambiguous where Commented is in scope.

data Line Source #

A line of comments.

Constructors

EmptyLine 
CommentLine !Int !Text

The number of # characters at the start of the comment, e.g. 2 for ## Section, and the text after them, without the one space after the # characters and without the white space at its end. The renderer writes a count below 1 as 1. It writes a text with line breaks as several comment lines with the same # characters, and the parser reads them back as several comments. U+0085, U+2028 and U+2029 count as line breaks here, because YAML 1.1 reads them as line breaks.

The comment at the end of a line in Comments is a text without a count. It keeps the # characters after the first one in its text.

Bundled Patterns

pattern Comment :: Text -> Line

A comment with one #. As a pattern, it matches every comment and ignores the number of # characters.

Instances

Instances details
NFData Line Source # 
Instance details

Defined in Yamlet.Internal.Syntax

Methods

rnf :: Line -> ()

Generic Line Source # 
Instance details

Defined in Yamlet.Internal.Syntax

Associated Types

type Rep Line 
Instance details

Defined in Yamlet.Internal.Syntax

type Rep Line = D1 ('MetaData "Line" "Yamlet.Internal.Syntax" "yamlet-1.0.0.1-2nRkbEnNUrLFBALTocq2AS" 'False) (C1 ('MetaCons "EmptyLine" 'PrefixI 'False) (U1 :: Type -> Type) :+: C1 ('MetaCons "CommentLine" 'PrefixI 'False) (S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 Int) :*: S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 Text)))

Methods

from :: Line -> Rep Line x

to :: Rep Line x -> Line

Show Line Source # 
Instance details

Defined in Yamlet.Internal.Syntax

Methods

showsPrec :: Int -> Line -> ShowS

show :: Line -> String

showList :: [Line] -> ShowS

Eq Line Source # 
Instance details

Defined in Yamlet.Internal.Syntax

Methods

(==) :: Line -> Line -> Bool

(/=) :: Line -> Line -> Bool

Ord Line Source # 
Instance details

Defined in Yamlet.Internal.Syntax

Methods

compare :: Line -> Line -> Ordering

(<) :: Line -> Line -> Bool

(<=) :: Line -> Line -> Bool

(>) :: Line -> Line -> Bool

(>=) :: Line -> Line -> Bool

max :: Line -> Line -> Line

min :: Line -> Line -> Line

type Rep Line Source # 
Instance details

Defined in Yamlet.Internal.Syntax

type Rep Line = D1 ('MetaData "Line" "Yamlet.Internal.Syntax" "yamlet-1.0.0.1-2nRkbEnNUrLFBALTocq2AS" 'False) (C1 ('MetaCons "EmptyLine" 'PrefixI 'False) (U1 :: Type -> Type) :+: C1 ('MetaCons "CommentLine" 'PrefixI 'False) (S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 Int) :*: S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 Text)))

Lines above a node

A comment on a line of its own belongs to the node below it. Above the first entry of a block collection, the lines up to the last empty line belong to the collection, e.g. a comment at the top of a file.

>>> input = "# The server.\n\n# The host.\nhost: localhost\n# The port.\nport: 80\n"
>>> T.putStr input
# The server.

# The host.
host: localhost
# The port.
port: 80
>>> printComments input
root before: [Comment "The server.",EmptyLine]
root.host (key) before: [Comment "The host."]
root.port (key) before: [Comment "The port."]

A block collection after - on the same line keeps all the lines above it, so that a comment above an item belongs to the item.

>>> input = "# The first server.\n- host: localhost\n# The second server.\n- host: example.com\n"
>>> T.putStr input
# The first server.
- host: localhost
# The second server.
- host: example.com
>>> printComments input
root[0] before: [Comment "The first server."]
root[1] before: [Comment "The second server."]

The rules in the sections below give some of these lines to a document or to the end of a collection instead, e.g. # a and # b below. The node below still gets # c.

>>> input = "# a\n---\nserver:\n  host: localhost\n  # b\n# c\nuser: admin\n"
>>> T.putStr input
# a
---
server:
  host: localhost
  # b
# c
user: admin
>>> printComments input
document before: [Comment "a"]
root.server (value) after: [Comment "b"]
root.user (key) before: [Comment "c"]

Comments at the end of a line

A comment at the end of a line belongs to the node that ends last before it on that line, if only spaces, a colon or a comma come between them. E.g. the value gets the comment in key: value # comment. In key: # comment, the key gets it if the value starts on a later line. Otherwise the value is empty and ends after the colon, so it gets the comment. A comment on the line of a block scalar header belongs to the block scalar.

>>> input = "host: localhost # a\nports: # b\n- 80\nproxy: # c\ntext: | # d\n  Hello.\n"
>>> T.putStr input
host: localhost # a
ports: # b
- 80
proxy: # c
text: | # d
  Hello.
>>> printComments input
root.host (value) inline: "a"
root.ports (key) inline: "b"
root.proxy (value) inline: "c"
root.text (value) inline: "d"

A comment at the end of a line that the rule above does not give to a node, e.g. after - , belongs to the node below it. If that node also has a comment at the end of its line, the first comment becomes a line above the node, e.g. # c below.

>>> input = "- # a\n  host: localhost # b\n- # c\n  'a string' # d\n"
>>> T.putStr input
- # a
  host: localhost # b
- # c
  'a string' # d
>>> printComments input
root[0] inline: "a"
root[0].host (value) inline: "b"
root[1] before: [Comment "c"]
root[1] inline: "d"

The same holds for a comment after the tag of a block collection.

>>> input = "server: !!map # a\n  host: localhost\n"
>>> T.putStr input
server: !!map # a
  host: localhost
>>> printComments input
root.server (value) inline: "a"

On the line of the --- marker, the document gets such a comment.

>>> input = "--- !!map # a\nhost: localhost\n"
>>> T.putStr input
--- !!map # a
host: localhost
>>> printComments input
document inline: "a"

Lines at the end of a collection

A comment below a scalar or an alias in a block collection belongs to the end of that node if it is indented deeper than the key or the - of its entry. Below the last item of a list without indentation, it belongs to the end of the list, by the rule below.

>>> input = "host: localhost\n  # a\n# b\nports:\n- 80\n  # c\n# d\n- 443\n  # e\n# f\nuser: admin\n"
>>> T.putStr input
host: localhost
  # a
# b
ports:
- 80
  # c
# d
- 443
  # e
# f
user: admin
>>> printComments input
root.host (value) after: [Comment "a"]
root.ports (key) before: [Comment "b"]
root.ports (value) after: [Comment "e"]
root.ports[0] after: [Comment "c"]
root.ports[1] before: [Comment "d"]
root.user (key) before: [Comment "f"]

Below a block scalar, such a line is part of the scalar if it is indented as deep as the content. Otherwise it belongs to the node below. E.g. # a below is a line of the text, and user gets # b.

>>> input = "text: |\n    Hello.\n    # a\n  # b\nuser: admin\n"
>>> T.putStr input
text: |
    Hello.
    # a
  # b
user: admin
>>> printComments input
root.user (key) before: [Comment "b"]

Thus the text has no place for the lines after a block scalar. They read back as the lines of the node below, or of the end of an outer collection.

Below a scalar or an alias key after ?, such a line belongs to the value: as a line above it if the : of the value follows, and as a line after it if the key has no value. A list or a mapping as the key keeps it. E.g. the value of a gets # b above it, the empty value of e gets # f after it, and the list key gets # d.

>>> input = "? a\n  # b\n: x\n? e\n  # f\n? - c\n  # d\n: y\n"
>>> T.putStr input
? a
  # b
: x
? e
  # f
? - c
  # d
: y
>>> printComments input
root.a (value) before: [Comment "b"]
root.e (value) after: [Comment "f"]
root.? (key) after: [Comment "d"]

Thus the text has no place for the lines after a scalar or an alias key. They read back as lines of the value.

A comment after the last entry of a block collection belongs to the end of the collection if it is indented at least as deep as the entries, and deeper than the key of the collection. Otherwise it belongs to the node below it, or to the end of an outer collection if no node is below it.

>>> input = "server:\n  ports:\n  - 80\n  # a\n  # b\n# c\nuser: admin\n"
>>> T.putStr input
server:
  ports:
  - 80
  # a
  # b
# c
user: admin
>>> printComments input
root.server (value) after: [Comment "a",Comment "b"]
root.user (key) before: [Comment "c"]

A comment before the closing bracket of a flow collection belongs to the end of the collection.

>>> input = "ports: [80, 443,\n  # a\n  ]\n"
>>> T.putStr input
ports: [80, 443,
  # a
  ]
>>> printComments input
root.ports (value) after: [Comment "a"]

Documents

The optional --- marker starts a document, and the optional ... marker ends it. The lines above the directives or the --- marker belong to the document. So do the comment on the line of the ... marker and the lines below it. Without the markers, the root gets these lines.

A comment on the line of the --- marker belongs to the document, unless the rule for comments at the end of a line gives it to a node.

>>> input = "# a\n--- # b\n# c\n\nentry: value\n\n# e\n...\n# f\n"
>>> T.putStr input
# a
--- # b
# c

entry: value

# e
...
# f
>>> printComments input
document before: [Comment "a"]
document inline: "b"
root before: [Comment "c",EmptyLine]
root after: [EmptyLine,Comment "e"]
document after: [Comment "f"]

Between two documents, the first empty line below the ... marker ends the lines of the first document. The empty line and the lines below it belong to the second document: to the lines above its --- marker, or to its root without the marker.

>>> input = "x: 1\n...\n# a\n\n# b\n---\ny: 2\n"
>>> T.putStr input
x: 1
...
# a

# b
---
y: 2
>>> printComments input
document after: [Comment "a"]
next document
document before: [EmptyLine,Comment "b"]

Without the ... marker, the first empty line below the root ends the lines of the root in the same way.

>>> input = "x: 1\n# a\n\n# b\n---\ny: 2\n"
>>> T.putStr input
x: 1
# a

# b
---
y: 2
>>> printComments input
root after: [Comment "a"]
next document
document before: [EmptyLine,Comment "b"]

The lines of a flow collection are between its brackets, so the lines below a flow collection root belong to the document, also without the ... marker.

>>> input = "[80, 443]\n# a\n"
>>> T.putStr input
[80, 443]
# a
>>> printComments input
document after: [Comment "a"]

The renderer writes the markers and the empty lines that these rules need, so that the lines read back at the same places. One exception: the empty lines at the end of a document can read back as the lines of the next document.

Empty lines

Empty lines go with the node below them, or with the end of the document. Thus, if a program removes an entry, the gap below the entry stays.

>>> input = "server:\n  host: localhost\n  # The end of the server.\n\nuser: admin\n"
>>> T.putStr input
server:
  host: localhost
  # The end of the server.

user: admin
>>> printComments input
root.server (value) after: [Comment "The end of the server."]
root.user (key) before: [EmptyLine]

Empty lines above a comment go with the comment. Each empty line is a line of its own.

>>> input = "host: localhost\n\n\n# The port.\nport: 80\n\nuser: admin\n"
>>> T.putStr input
host: localhost


# The port.
port: 80

user: admin
>>> printComments input
root.port (key) before: [EmptyLine,EmptyLine,Comment "The port."]
root.user (key) before: [EmptyLine]

One place is an exception. Above the first entry of a block collection, the last empty line stays with the collection. If the lines of a block collection do not end with an empty line, e.g. lines that a program added, the renderer can write one below them, so that they read back as the lines of the collection. The added empty line reads back as their last line.

>>> input = "# The file.\n\nhost: localhost\n"
>>> T.putStr input
# The file.

host: localhost
>>> printComments input
root before: [Comment "The file.",EmptyLine]