mk-fg / pretty-yaml

PyYAML-based module to produce a bit more pretty and readable YAML-serialized data
Do What The F*ck You Want To Public License
135 stars 29 forks source link

Multiline String as block and quoted Strings #26

Closed pansen closed 6 years ago

pansen commented 6 years ago

Hi!

I have some OpenAPI schema definition, that I'm extracting via ApiSpec.

    ---
    x-extension: value
    post:
      # headline/name of the resource
      operationId: users create
      summary: Register user
      description: |
        Imagine all the users living for today

        Imagine there's no countries
        It isn't hard to do
        Nothing to kill or die for
        And no religion too

        Imagine all the users living life in peace, you
        You may say I'm a dreamer
        But I'm not the only one
        I hope some day you'll join us
        And the world will be as one

      security:
        - APIKeyHeader: []

      # this will appear as grouping in the left-side menu
      tags:
      - Legacy API

      consumes:
      - application/json
      produces:
      - application/json

      parameters:
      - in: body
        name: body
        description: Foo bar
        required: true
        schema:
          $ref: '#/components/schemas/FooBodySchema'

Apispec is doing all the heavy lifting, but I changed the yaml library to pretty-yaml to get rid of the Python type hints.

Question

Given the yaml above, how can I accomplish to receive multiline blocks as a block

      description: |
        Imagine all the users living for today

        Imagine there's no countries
        It isn't hard to do
        Nothing to kill or die for
        And no religion too

and

have single line Strings quoted

        schema:
          $ref: '#/components/schemas/FooBodySchema'

Currently I'm using

pyaml.dump(my_spec, safe=True, force_embed=False, vspacing=[2, 1], string_val_style='"')

which unfortunately puts the mutline Strings in simple quotes as well.

Thank you :)

mk-fg commented 6 years ago

Hi,

Current behavior in this module is to use explicitly-specified string style unconditionally, i.e. for all strings, so not possible to do what you want via simple parameter. https://github.com/mk-fg/pretty-yaml/blob/370130d/pyaml/__init__.py#L113-L136

What I'd probably do is to subclass UnsafePrettyYAMLDumper and override represent_stringish method there to check for newlines and using style = '|' for these and calling original method or using style = "'" for everything else. Don't remember if using UnsafePrettyYAMLDumper.add_representer(str_type, myfunc) will do the same, maybe can be used instead of subclassing, though latter is probably same LoC-wise and won't alter global stuff.

mk-fg commented 6 years ago

Actually, if you want to change existing yaml doc without breaking formatting, comments in there or anything like that, maybe also check out ruamel.yaml module, which I've used for that recently and found to be very powerful for any kind of humane yaml stuff (esp. preserving comments is like a killer feature!).

EDIT: wanted to add it to README too, but apparently did so a while ago already, so you probably seen it there.

pansen commented 6 years ago

Awesome, thanks a lot @mk-fg. I will check your suggestions and respond my final solution. :)