google / jsonnet

Jsonnet - The data templating language
http://jsonnet.org
Apache License 2.0
6.97k stars 440 forks source link

Support |||- from YAML #289

Open guoshimin opened 7 years ago

guoshimin commented 7 years ago

This will send jsonnet spinning, consuming 100% of CPU:

jsonnet -e '|||-
  abc
|||'

Tested with v0.9.0.

I was trying to see if jsonnet supported chomping the final newline in text blocks similar to how it's done in YAML. Consider this both a bug report and a feature request :D

sparkprime commented 7 years ago

Thanks for the report, this is a dup of a previous bug which is fixed on master. Perhaps another release is in order...

$ jsonnet -e '|||-
>   abc
> |||'
STATIC ERROR: <cmdline>:1:1: Text block syntax requires new line after |||.
sparkprime commented 7 years ago

I'm curious to know why you want this?

guoshimin commented 7 years ago

Oh sorry, should have searched the issues first. How feasible is it to incorporate this new syntax to mean "chomp the final newline"?

On Wed, Jan 18, 2017, 8:20 PM Dave Cunningham notifications@github.com wrote:

Thanks for the report, this is a dup of a previous bug which is fixed on master. Perhaps another release is in order...

$ jsonnet -e '|||-

abc |||' STATIC ERROR: :1:1: Text block syntax requires new line after |||.

— You are receiving this because you authored the thread.

Reply to this email directly, view it on GitHub https://github.com/google/jsonnet/issues/289#issuecomment-273678459, or mute the thread https://github.com/notifications/unsubscribe-auth/ALPcHVhB12ZLiNFIEcFYf4P3UirEjHEXks5rTuRwgaJpZM4LnN2z .

sparkprime commented 7 years ago

Pretty feasible I should think. I guess this is only useful if you only have one line?

sparkprime commented 7 years ago

I'm struggling to understand why anyone would want to have a paragraph of text with no terminating \n :)

guoshimin commented 7 years ago

The use case is visually concatenating two text blocks together:

local a = ...  // text block a
local b = ...  // text block b
|||
  %s
  %s
||| % [a, b]

If I want b to immediately follow a, I need to chomp the last newline in a.

guoshimin commented 7 years ago

(Sorry for the late reply. Github often doesn't email me for issue and PR updates.)

sparkprime commented 7 years ago

Ok that sounds reasonable. It is not hard to add the support. I think a reasonable approach is that the reformatter converts (without consent and with no way to turn it off)

|||-
    foo

|||

to

|||
    foo
|||

With that mode of operation, the presence of a \n in the last byte of the string literal indicates whether |||- should be emitted by the formatter. In other words there is no other state needed to store whether or not |||- was used.

Changes needed are simple:

1) Modify lexer to accept |||-, suppress terminating \n 2) Modify reformatter to emit ||| if there is a terminating \n, |||- otherwise

After (1) one should be able to test the JSON output. However without (2) jsonnet fmt will produce code that does not parse.

vergenzt commented 2 weeks ago

I know this is a pretty old issue... but is there still openness to adding this syntax? I'm aware that std.rstripChars(..., '\n') would accomplish a similar goal, but it does have the unfortunate side effect that any number of trailing newlines are stripped rather than just one trailing newline (which is what I would expect from |||-, and I think is what the documented behavior should be).

I really like the approach from https://github.com/google/jsonnet/issues/289#issuecomment-277320908.

Edit: My use case for this is also that I'm trying to concatenate multiple multiline string literals without extra newlines in between.