Search code examples
pythonyamlpyyaml

Any yaml libraries in Python that support dumping of long strings as block literals or folded blocks?


I'd like to be able to dump a dictionary containing long strings that I'd like to have in the block style for readability. For example:

foo: |
  this is a
  block literal
bar: >
  this is a
  folded block

PyYAML supports the loading of documents with this style but I can't seem to find a way to dump documents this way. Am I missing something?


Solution

  • import yaml
    
    class folded_unicode(unicode): pass
    class literal_unicode(unicode): pass
    
    def folded_unicode_representer(dumper, data):
        return dumper.represent_scalar(u'tag:yaml.org,2002:str', data, style='>')
    def literal_unicode_representer(dumper, data):
        return dumper.represent_scalar(u'tag:yaml.org,2002:str', data, style='|')
    
    yaml.add_representer(folded_unicode, folded_unicode_representer)
    yaml.add_representer(literal_unicode, literal_unicode_representer)
    
    data = {
        'literal':literal_unicode(
            u'by hjw              ___\n'
             '   __              /.-.\\\n'
             '  /  )_____________\\\\  Y\n'
             ' /_ /=== == === === =\\ _\\_\n'
             '( /)=== == === === == Y   \\\n'
             ' `-------------------(  o  )\n'
             '                      \\___/\n'),
        'folded': folded_unicode(
            u'It removes all ordinary curses from all equipped items. '
            'Heavy or permanent curses are unaffected.\n')}
    
    print yaml.dump(data)
    

    The result:

    folded: >
      It removes all ordinary curses from all equipped items. Heavy or permanent curses
      are unaffected.
    literal: |
      by hjw              ___
         __              /.-.\
        /  )_____________\\  Y
       /_ /=== == === === =\ _\_
      ( /)=== == === === == Y   \
       `-------------------(  o  )
                            \___/
    

    For completeness, one should also have str implementations, but I'm going to be lazy :-)