Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multiline strings are not emitted in the literal/folded style #98

Open
ltrzesniewski opened this issue May 10, 2022 · 0 comments
Open

Comments

@ltrzesniewski
Copy link

I noticed that SharpYaml doesn't emit multiline strings in the literal or folded style.

At first, I thought I missed a setting, but after digging a bit in the code this seems unintentional:

First, here's a repro to show what I mean:

using System;
using System.Collections.Generic;

namespace ConsoleApp;

public static class Program
{
    public static void Main()
    {
        var data = new Dictionary<string, string> { { "Key", "Foo\r\nBar" } };

        Console.WriteLine(new YamlDotNet.Serialization.SerializerBuilder().Build().Serialize(data));
        Console.WriteLine("---");
        Console.WriteLine(new SharpYaml.Serialization.Serializer(new() { EmitTags = false }).Serialize(data));
    }
}

Output:

Key: >-
  Foo

  Bar

---
Key: "Foo\r\nBar"

Bonus points if SharpYaml could use literal style by default instead: 🙂

Key: |-
  Foo
  Bar

I suppose you may want to add a setting to tell if the serialized value needs to be round-trippable regarding the \r character, as YAML would normalize the line break to \n on deserialization.


Here's what happens:

The following code turns ScalarStyle.Folded into ScalarStyle.DoubleQuoted when isBlockAllowed is false:

if (style == ScalarStyle.Literal || style == ScalarStyle.Folded)
{
if (!scalarData.isBlockAllowed || flowLevel != 0 || isSimpleKeyContext)
{
style = ScalarStyle.DoubleQuoted;
}
}

Here, isBlockAllowed is set to false when special_characters is true:

if (space_break || special_characters)
{
scalarData.isFlowPlainAllowed = false;
scalarData.isBlockPlainAllowed = false;
scalarData.isSingleQuotedAllowed = false;
scalarData.isBlockAllowed = false;
}

And here, special_characters is set to true when !buffer.IsPrintable():

if (!special_characters && !buffer.IsPrintable())
{
special_characters = true;
}

CR and LF are not considered printable:

internal static bool IsPrintable(char character)
{
return
(character >= '\x20' && character <= '\x7E') ||
character == '\x85' ||
(character >= '\xA0' && character <= '\xD7FF') ||
(character >= '\xE000' && character <= '\xFFFD');
}

I'm not sure at which point a change would need to be applied. YamlDotNet has a different logic for setting isBlockAllowed to false.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants