mirror of
https://github.com/apple/pkl.git
synced 2026-01-14 07:33:40 +01:00
New lines in a multi-line string not properly escaped in JSON output #273
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Originally created by @TheMadLeprechaun on GitHub (Feb 3, 2025).
When creating a multi-line string, the resulting JSON output does not properly escape the new line character.
Example
file.pkl:When running
pkl eval --format json file.pklthe output isThe expected output would be the following since JSON requires
\\ninstead of\nI'm new to pkl so I might be missing something but I couldn't find anything about this.
@HT154 commented on GitHub (Feb 3, 2025):
This doesn't seem right to me. If this were the case, the string in the JSON data, once decoded would be
Can you share more about where this information is from or how you determined it?
@bioball commented on GitHub (Feb 3, 2025):
JSON uses
\nto represent newlines (see https://datatracker.ietf.org/doc/html/rfc7159#section-7)If you want to emit
\\nin JSON (which means the literal\andncharacters), you need to represent\nas verbatim characters in Pkl too. To do that, you can either escape the slash, or use custom string delimiters.Escaping the slash:
Custom string delimiters:
@TheMadLeprechaun commented on GitHub (Feb 3, 2025):
So, the main reason I'm using pkl is for readability. The software that the JSON goes into allows for embedded scripts. Since JSON doesn't support multi-lines in the actual JSON, I started using pkl. Otherwise I'd have to put it all in a very unreadable single line. Using the built in multi-line support of pkl it looks like this:
The built in multi-line automatically normalizes the line breaks to
\nso it looks likeIf I do
I get
Doing
Gets the same output
This is where I found the
\\ninformation outside of my own experiences: https://stackoverflow.com/questions/42068/how-do-i-handle-newlines-in-jsonIn my use case, it's a different error but it's for the same reason. The error being along the lines of "there is an invalid control character in the string."
If it helps, the software the JSON goes to is BMC Control-M. I probably should have made clear that the issue is with the built in multi-line support as opposed to adding a new line to a string. My bad. I was using this as reference: https://pkl-lang.org/main/current/language-reference/index.html#multiline-strings
Clear as mud I hope. 😛
@HT154 commented on GitHub (Feb 3, 2025):
Ah, I see what happened here! The example in that SO post is in js and shows a JSON object serialized inside a string. Given this js:
The escaped backslash
\\tells the js parser to produce a literal\in the resulting string. Thus, the variabledatahas valueThis is syntactically valid JSON
It's not necessary to add this extra level of escaping in Pkl! Pkl knows how to encode any string value as valid JSON. The equivalent Pkl code here is
And when rendered to JSON, this produces the exact same output:
The difference here is that in the SO post the js code must contend with an extra layer of string escaping that is not required when working in Pkl.
If you're finding you need to do this to get the JSON working with your target system, it may be expecting string values to be escaped an extra time. This would be a quirk of that system and not related to Pkl or its JSON implementation.
Given this, you might consider doing something like this instead:
Or maybe even better, set up an output converter in your module in the name of reusability:
@TheMadLeprechaun commented on GitHub (Feb 3, 2025):
In the original output, all of the backslashes are properly escaped in the Windows paths in the JSON output it's the literal
\nthat pkl puts out that's the issue.I used
replaceAllsince I got an error just tryingreplaceand
These both give this output
So, on top of the excessive number of
\, it gives\\\\n\n. If I do either of the above and remove the literal\nthen the output has all of the\but still has the\nthat pkl puts in.From https://pkl-lang.org/main/current/language-reference/index.html#multiline-strings
This normalization is the issue. It sounds like there isn't a way to manipulate that normalized line break. It's not a major problem. Just something I was curious about if it was something specific to the JSON implementation or pkl. Writing these in pkl is still significantly more readable.
@bioball commented on GitHub (Feb 3, 2025):
If you want a newline in Pkl to turn into
\\nin the JSON output, you can actually just doreplaceAll("\n", "\\n").For example:
And here's the output:
@TheMadLeprechaun commented on GitHub (Feb 3, 2025):
@bioball That's exactly what I was looking for. Thanks everyone.