This can be relatively easily done, the only "hurdle" being how to
indicate which of the spaces in the string, that needs to be
represented as a folded scalar, needs to become a fold. The literal scalar
has explicit newlines containing that information, but this cannot
be used for folded scalars, as they can contain explicit newlines e.g. in
case there is leading whitespace and also needs a newline at the end
in order not to be represented with a stripping chomping indicator (>-)
import sys
import ruamel.yaml
folded = ruamel.yaml.scalarstring.FoldedScalarString
literal = ruamel.yaml.scalarstring.LiteralScalarString
yaml = ruamel.yaml.YAML()
data = dict(
foo=literal('this is a\nblock literal\n'),
bar=folded('this is a folded block\n'),
)
data['bar'].fold_pos = [data['bar'].index(' folded')]
yaml.dump(data, sys.stdout)
which gives:
foo: |
this is a
block literal
bar: >
this is a
folded block
The fold_pos attribute expects a reversable iterable, representing positions
of spaces indicating where to fold.
If you never have pipe characters ('|') in your strings you
could have done something like:
import re
s = 'this is a|folded block\n'
sf = folded(s.replace('|', ' ')) # need to have a space!
sf.fold_pos = [x.start() for x in re.finditer('\|', s)] # | is special in re, needs escaping
data = dict(
foo=literal('this is a\nblock literal\n'),
bar=sf, # need to have a space
)
yaml = ruamel.yaml.YAML()
yaml.dump(data, sys.stdout)
which also gives exactly the output you expect