feat: add |||- chomped text block syntax (#773)

Resolves google/jsonnet#289

Companion PR to google/jsonnet#1175
This commit is contained in:
Tim Vergenz 2025-01-20 16:45:15 -05:00 committed by GitHub
parent a45dd8a8f4
commit e6f64e89f1
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 36 additions and 4 deletions

View File

@ -685,7 +685,7 @@ func (c *FixIndentation) Visit(expr ast.Node, currIndent indent, crowded bool) {
node.BlockIndent = strings.Repeat(" ", currIndent.base+c.Options.Indent) node.BlockIndent = strings.Repeat(" ", currIndent.base+c.Options.Indent)
node.BlockTermIndent = strings.Repeat(" ", currIndent.base) node.BlockTermIndent = strings.Repeat(" ", currIndent.base)
c.column = currIndent.base // blockTermIndent c.column = currIndent.base // blockTermIndent
c.column += 3 // "|||" c.column += 3 // always "|||" (never "|||-" because we're only accounting for block end)
case ast.VerbatimStringSingle: case ast.VerbatimStringSingle:
c.column += 3 // Include @, start and end quotes c.column += 3 // Include @, start and end quotes
for _, r := range node.Value { for _, r := range node.Value {

View File

@ -467,7 +467,11 @@ func (u *unparser) unparse(expr ast.Node, crowded bool) {
u.write(node.Value) u.write(node.Value)
u.write("'") u.write("'")
case ast.StringBlock: case ast.StringBlock:
u.write("|||\n") u.write("|||")
if node.Value[len(node.Value)-1] != '\n' {
u.write("-")
}
u.write("\n")
if node.Value[0] != '\n' { if node.Value[0] != '\n' {
u.write(node.BlockIndent) u.write(node.BlockIndent)
} }
@ -481,6 +485,9 @@ func (u *unparser) unparse(expr ast.Node, crowded bool) {
u.write(node.BlockIndent) u.write(node.BlockIndent)
} }
} }
if node.Value[len(node.Value)-1] != '\n' {
u.write("\n")
}
u.write(node.BlockTermIndent) u.write(node.BlockTermIndent)
u.write("|||") u.write("|||")
case ast.VerbatimStringDouble: case ast.VerbatimStringDouble:

View File

@ -719,6 +719,13 @@ func (l *lexer) lexSymbol() error {
if r == '|' && strings.HasPrefix(l.input[l.pos.byteNo:], "||") { if r == '|' && strings.HasPrefix(l.input[l.pos.byteNo:], "||") {
commentStartLoc := l.tokenStartLoc commentStartLoc := l.tokenStartLoc
l.acceptN(2) // Skip "||" l.acceptN(2) // Skip "||"
var chompTrailingNl bool = false
if l.peek() == '-' {
chompTrailingNl = true
l.next()
}
var cb bytes.Buffer var cb bytes.Buffer
// Skip whitespace // Skip whitespace
@ -775,7 +782,13 @@ func (l *lexer) lexSymbol() error {
return l.makeStaticErrorPoint("Text block not terminated with |||", commentStartLoc) return l.makeStaticErrorPoint("Text block not terminated with |||", commentStartLoc)
} }
l.acceptN(3) // Skip '|||' l.acceptN(3) // Skip '|||'
l.emitFullToken(tokenStringBlock, cb.String(),
var str string = cb.String()
if chompTrailingNl {
str = str[:len(str)-1]
}
l.emitFullToken(tokenStringBlock, str,
stringBlockIndent, stringBlockTermIndent) stringBlockIndent, stringBlockTermIndent)
l.resetTokenStart() l.resetTokenStart()
return nil return nil
@ -793,7 +806,7 @@ func (l *lexer) lexSymbol() error {
if r == '/' && strings.HasPrefix(l.input[l.pos.byteNo:], "*") { if r == '/' && strings.HasPrefix(l.input[l.pos.byteNo:], "*") {
break break
} }
// Not allowed ||| in operators // Not allowed ||| in operators (accounts for |||-)
if r == '|' && strings.HasPrefix(l.input[l.pos.byteNo:], "||") { if r == '|' && strings.HasPrefix(l.input[l.pos.byteNo:], "||") {
break break
} }

1
testdata/block_string_chomped.golden vendored Normal file
View File

@ -0,0 +1 @@
"foo\nbar\nbaz"

5
testdata/block_string_chomped.jsonnet vendored Normal file
View File

@ -0,0 +1,5 @@
|||-
foo
bar
baz
|||

View File

View File

@ -0,0 +1 @@
"foo bar baz all one line"

View File

@ -0,0 +1,5 @@
|||-
foo bar baz
||| + |||-
all one line
|||

View File