Reputation: 27
I am trying to make up some YAML files and I am struggling to get the YAML files in a correct format. I am trying to get the strings of the values all be on the same indentation but I cannot seem to get it to work.
ResourceIndicators:
version: 1.0.0
name: This is the name
neType: Text
category: Text
description: The is the first line of the sentence and then we continue
on to the second line but this line should be indented to match the
first line of the string.
This is what I have but I am looking for:
ResourceIndicators:
version: 1.0.0
name: This is the name
neType: Text
category: Text
description: The is the first line of the sentence and then we continue
on to the second line but this line should be indented to
match the first line of the string.
Upvotes: 2
Views: 2449
Reputation: 76578
There is no option or simple way in ruamel.yaml
(or PyYAML) to get what you want.
The value for the description
mapping key is a normal scalar, and you probably have set the output width to 70
(or similar) to get that result. The value is a plain style scalar, which can be broken on any space surrounded by non-space characters.
You might have considered using block style literal scalars, but although
description: |-
The is the first line of the sentence and then we continue
on to the second line but this line should be indented to match the
first line of the string.
almost looks similar, it actually loads with two extra newlines in that string. Even if you pre-process that scalar before dumping and post process it after loading to try and use an explicit block indentation indicator will not give you more than 9 positions (as it is restricted to a single digit) and you have more than that.
If the following format is acceptable:
ResourceIndicators:
version: 1.0.0
name: This is the name
neType: Text
category: Text
description: |-
The is the first line of the sentence and then we continue
on to the second line but this line should be indented to
match the first line of the string.
You can do that with a little function wrapped
:
import sys
import textwrap
import ruamel.yaml
from ruamel.yaml.scalarstring import PreservedScalarString
yaml_str = """\
ResourceIndicators:
version: 1.0.0
name: This is the name
neType: Text
category: Text
description: The is the first line of the sentence and then we continue
on to the second line but this line should be indented to match the
first line of the string.
"""
def wrapped(s, width=60):
return PreservedScalarString('\n'.join(textwrap.wrap(s, width=width)))
yaml = ruamel.yaml.YAML()
yaml.preserve_quotes = True
data = yaml.load(yaml_str)
data['ResourceIndicators']['description'] = \
wrapped(data['ResourceIndicators']['description'])
yaml.dump(data, sys.stdout)
But beware that after loading you have to replace the newlines in the value with spaces.
If that is not an option you need to create a class "IndentedPlainString" with a special representer that does the extra indentation.
Upvotes: 3