Keeping linebreaks with formats.yaml.generate

Using the Home-Manager module for Beets, which is in turn using pkgs.formats.yaml.generate to format Beets’ configuration file, I’m trying to generate the following output:

item_fields:
    disc_with_title: |
        str = u''
        if disctotal > 1:
            str += u'CD %i' % (disc)
            if disctitle != u'':
                str += u' - %s' % (disctitle)
        return str

This is what I ended up using:

      item_fields = {
        disc_with_title = ''str = u'''
if disctotal > 1:
    str += u'CD %i' % (disc)
    if disctitle != u''':
        str += u' - %s' % (disctitle)
return str'';
      };

I also tried a few different variants - adding a line break around the surrounding '', adding a | (as it’s how YAML formats multiline strings)… but I always end up with the following output:

item_fields:
  disc_with_title: "str = u''\nif disctotal > 1:\n    str += u'CD %i' % (disc)\n \
    \   if disctitle != u'':\n        str += u' - %s' % (disctitle)\nreturn str"

How can I ensure linebreaks are kept?

Keep the multiline string indicators ('') on separate lines. You’ll be able to indent the string correctly in Nix and it’ll output to yaml without the indentation.

Note also that in a multiline string, ' is escaped by '''. So '' becomes ''''''.

      item_fields = {
        disc_with_title = ''
          str = u''''''
          if disctotal > 1:
            str += u'''CD %i''' % (disc)
            if disctitle != u'''''':
              str += u''' - %s''' % (disctitle)
          return str
        '';
      };

I initially had the multiline string markers ('') on separate lines, it didn’t make any difference. I can also confirm that escaping the double single quotes with a third one outputs two as expected (which you can see in the output I pasted).

Which makes me think this module is doing something a bit unconventional maybe?

Hmm, I see what you mean. It is valid yaml and it does include linebreaks, but it isn’t formatted the way you’d like?

At the moment it isn’t possible to influence the way formats.yaml.generate formats the yaml. From its implementation you can see it uses remarshal, which uses pyyaml to do the formatting. remarshal does have options to influence the formatting, but nixpkgs’ formats.yaml.generate doesn’t allow setting those atm.

I’m not entirely sure why this is the default, but the application reading the configuration file should be able to properly interpret the \n to get the same string as you wrote in Nix, regardless of the format.

1 Like

I was somehow assuming that the formatting wouldn’t be correct, but it is parsed as expected indeed - so it really is a non-issue, thanks!

1 Like